Форум программистов, компьютерный форум, киберфорум
С++ для начинающих
Войти
Регистрация
Восстановить пароль
Карта форума Темы раздела Блоги Сообщество Поиск Заказать работу  
 
Рейтинг 4.50/4: Рейтинг темы: голосов - 4, средняя оценка - 4.50
0 / 0 / 0
Регистрация: 26.01.2016
Сообщений: 45
1

Что происходит с лишними байтами double при сравнении с меньшим по размеру float?

06.12.2017, 16:57. Показов 788. Ответов 18
Метки нет (Все метки)

Author24 — интернет-сервис помощи студентам
Всем привет, специально создал в разделе для новичков, ибо звучит сие глупейше..

итак немного теории, все мы знаем, что float это 4 байта, а double 8
из этого следуя мы понимаем, что присваивая значение:

float a = 1.0;
в памяти у нас занимаются 4 байта, и по идее там 1.000000 (6 знаков после запятой)

с double соответственно.

а теперь магический вопрос:
C++
1
2
3
4
5
6
7
8
9
10
11
12
13
int main() 
{ 
float a = (float)44.47647f; 
double b = (double)44.476470947265625;
if((float)a == (double)b)
{ 
printf("equals \n"); 
} 
if((double)b > (double)a) 
{
 printf(" bigger\n"); 
} 
}
внимание вопрос, какого X=>Y ???
0
Programming
Эксперт
94731 / 64177 / 26122
Регистрация: 12.04.2006
Сообщений: 116,782
06.12.2017, 16:57
Ответы с готовыми решениями:

float to double. Как происходит приведение типов?
double x = 1.01F; float y = 1.01F; Console.Write(x); // 1.00999 Console.WriteLine();...

Ошибка при сравнении double и регулярного выражения
Написал регулярное выражение для считывания средней оценки студента, но при вводе этой средней...

Float imprecision - что происходит?
На си пишу: #include <cs50.h> ... changeOwed = get_float("Change owed: \n"); Ввожу 4.2 В...

Float или Double: что и в каком случае использовать
Когда лучше использовать один тип а когда второй. Читал,float нужно использовать когда в памяти...

18
techpriest
634 / 213 / 57
Регистрация: 27.02.2014
Сообщений: 1,180
06.12.2017, 17:01 2
Если коротко, то потому, что
C++
1
(float)a != (double)a
П.С. Я тут чушь написал.
0
0 / 0 / 0
Регистрация: 26.01.2016
Сообщений: 45
06.12.2017, 17:02  [ТС] 3
Цитата Сообщение от Mirmik Посмотреть сообщение
Если коротко, то потому, что
если вы скомпилите, то эти числа РАВНЫ
0
techpriest
634 / 213 / 57
Регистрация: 27.02.2014
Сообщений: 1,180
06.12.2017, 17:02 4
П.С. У меня выводит только equals
0
0 / 0 / 0
Регистрация: 26.01.2016
Сообщений: 45
06.12.2017, 17:12  [ТС] 5
Цитата Сообщение от Mirmik Посмотреть сообщение
П.С. У меня выводит только equals
это и значит что они равны, но какого ?

Добавлено через 6 минут
да, похоже надо уточнить. Вопрос в том, почему они равны?
0
techpriest
634 / 213 / 57
Регистрация: 27.02.2014
Сообщений: 1,180
06.12.2017, 17:13 6
Опять же, если кратко 44.47647f не имеет точного представления в float выражении. Поэтому компилятор вместо него подставляет ближайшее, оладающее таким представлением. То есть, числа, изначально то как раз были равны.
0
0 / 0 / 0
Регистрация: 26.01.2016
Сообщений: 45
06.12.2017, 17:16  [ТС] 7
Цитата Сообщение от Mirmik Посмотреть сообщение
Опять же, если кратко 44.47647f не имеет точного представления в float выражении
в смысле не имеет точного представления? куда точнее? скастуйте а к double результат один они равны о_О
0
techpriest
634 / 213 / 57
Регистрация: 27.02.2014
Сообщений: 1,180
06.12.2017, 17:18 8
http://rextester.com/SPDYU56709

Добавлено через 1 минуту
Вы не сможете найти такую комбинацию битов в объекте типа float, чтобы результат его интерпретации оказался вточности равен 44.47647. Довольно типичная проблема при переходе между системами счисления.
0
0 / 0 / 0
Регистрация: 26.01.2016
Сообщений: 45
06.12.2017, 17:55  [ТС] 9
Цитата Сообщение от Mirmik Посмотреть сообщение
Вы не сможете найти такую комбинацию битов в объекте типа float,
да я и не спорю, но у нас значение числа в 4х байтах не может быть равно числу в 8 байтах, и уж темболее заполненным.
и я никак не возьму в толк, почему при касте влота в дабл, я получаю то-же значение, хотя поидее там должны быть нули.
0
techpriest
634 / 213 / 57
Регистрация: 27.02.2014
Сообщений: 1,180
06.12.2017, 18:29 10
C++
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
#include <gxx/debug/dprint.h>
#include <iostream>
#include <iomanip>
 
int main() {
    std::cout << std::setprecision(20) << 44.476470947265625 << std::endl;
    std::cout << std::setprecision(20) << 44.47647f << std::endl;
 
    dprhexln(44.476470947265625);
    dprhexln((double)44.47647f);    
    dprbinln(44.476470947265625);
    dprbinln((double)44.47647f);    
 
    dprhexln((float)44.476470947265625);
    dprhexln(44.47647f);
    dprbinln((float)44.476470947265625);
    dprbinln(44.47647f);
 
    /*
        44.476470947265625
        44.476470947265625
 
        40463CFD00000000
        40463CFD00000000
        0100000001000110001111001111110100000000000000000000000000000000
        0100000001000110001111001111110100000000000000000000000000000000
 
        4231E7E8
        4231E7E8
        01000010001100011110011111101000
        01000010001100011110011111101000
    */
}
Нули то как раз и на месте.
0
зомбяк
1584 / 1218 / 345
Регистрация: 14.05.2017
Сообщений: 3,939
06.12.2017, 18:31 11
но у нас значение числа в 4х байтах не может быть равно числу в 8 байтах, и уж темболее заполненным.
и я никак не возьму в толк, почему при касте влота в дабл, я получаю то-же значение, хотя поидее там должны быть нули
Сделай вот так:
C++
1
a == *(reinterpret_cast<float *>(&b))
получишь сравнение 4 байтов float с первыми 4мя байтами double.

А чтоб "по идее там должны быть нули" - сделай вот так:
C++
1
2
3
4
5
6
7
float a = (float)44.47647f; 
double a2 = 0;
memcpy(&a2, &a, sizeof(float));
double b = (double)44.476470947265625;
if(a2 == b)
{
}
0
techpriest
634 / 213 / 57
Регистрация: 27.02.2014
Сообщений: 1,180
06.12.2017, 18:34 12
Проблема в том, что вы думаете в десятичной системе счисления. Числа, записанные в десятичной системе счисления не всегда красиво выглядят в двоичной и наоборот.

Как вам, например, (double)0.9:
0011111111101100110011001100110011001100110011001100110011001101
0
зомбяк
1584 / 1218 / 345
Регистрация: 14.05.2017
Сообщений: 3,939
06.12.2017, 18:35 13
Только я уверен что ни в *(reinterpret_cast<float *>(&b)), ни в a2 никакого значения наподобие 44.47647 не будет. Потому что https://ru.wikipedia.org/wiki/... й_точности vs https://ru.wikipedia.org/wiki/... й_точности - имеют ну совершенно разное разбиение по битам.
0
techpriest
634 / 213 / 57
Регистрация: 27.02.2014
Сообщений: 1,180
06.12.2017, 18:55 14
При сранении бинарного представления надо помнить, что мантиса double сдвинута относительно float, а также не забыть про little endian
0
Эксперт .NET
10563 / 6487 / 1506
Регистрация: 25.05.2015
Сообщений: 19,654
Записей в блоге: 14
06.12.2017, 19:51 15
Цитата Сообщение от Mimik_fc7 Посмотреть сообщение
Вопрос в том, почему они равны?
Просто так совпало. Вы выбрали числа до и после приведения типа.
Что происходит с лишними байтами double при сравнении с меньшим по размеру float?

Проверить двоичное и 16-ричное представление можно здесь: https://babbage.cs.qc.cuny.edu... cimal.html

Никогда не сравнивайте числа с плавающей точкой операцией == или !=. Возможно даже вот такое: https://www.cyberforum.ru/blog... g4674.html
0
0 / 0 / 0
Регистрация: 26.01.2016
Сообщений: 45
07.12.2017, 08:54  [ТС] 16
Цитата Сообщение от TRam_ Посмотреть сообщение
А чтоб "по идее там должны быть нули" - сделай вот так:
и они будут равны =)))
0
Эксперт .NET
10563 / 6487 / 1506
Регистрация: 25.05.2015
Сообщений: 19,654
Записей в блоге: 14
07.12.2017, 09:11 17
Вы вовсе не float с double сравниваете.
Перед сравнением, оба операнда приводятся к одинаковому типу. Точнее один, который float, приводится к double.
При приведении от float к double, 44.4764709 превращается в 44.476470947265625.
Но это число у вас уже есть и, очевидно, получено оно именно таким приведением типа.
Поэтому операнды и в двоичном виде эквивалентны.

Никакой магии.
0
0 / 0 / 0
Регистрация: 26.01.2016
Сообщений: 45
07.12.2017, 09:19  [ТС] 18
Цитата Сообщение от Rius Посмотреть сообщение
Вы вовсе не float с double сравниваете
Да, я понимаю, что при сравнении компилятор сам кастит типы, тут дело в другом, я почитал всю инфу что накидали, немного прояснилось, но самое главное, ответ крылся в кастах, самое интересное, это если преобразовать оба числа в HEX то они будут разные =) и даже битовые виды абсолютно разные. я помню, что у компилятора, есть настройка строгой типизации, похоже надо бы ее включить.
0
techpriest
634 / 213 / 57
Регистрация: 27.02.2014
Сообщений: 1,180
07.12.2017, 12:17 19
Я выше приводил представления наших пациентов в бинарном коде:

C++
1
2
3
44.47647f
double 0100000001000110001111001111110100000000000000000000000000000000
float  01000010001100011110011111101000
Посмотрим подробнее:
C++
1
2
3
знак    экспонента          мантиса
0       10000000100        0110001111001111110100000000000000000000000000000000
0       10000100           01100011110011111101000
Как видите экспоненты записываются в смещенном коде (они равны).
Мантисы задают дробную часть и также равны.
0
07.12.2017, 12:17
IT_Exp
Эксперт
87844 / 49110 / 22898
Регистрация: 17.06.2006
Сообщений: 92,604
07.12.2017, 12:17
Помогаю со студенческими работами здесь

Записать в железку значение float, но тремя байтами
Есть железяка. Необходимо записать в неё, значение float но тремя байтами. Разработчики выслали...

Казусы с double и float при преобразовании в string
Всем привет. Хотелось бы узнать почему когда выполняю такой код: void __fastcall...

Разные результаты при расчетах с float и double
Здравствуйте! Почему при расчете с float и double получаю разные результаты? #include &lt;iostream&gt;...

Почему при преобразования из float в double коверкается число?
float fll=34.23; cout &lt;&lt; &quot; fll=&quot;&lt;&lt; fll; //Вот тут я ввожу double dub; dub =...

При смене Float на double программа выдает нули
Доброго времени. При вводе следующего кода float f; scanf(&quot;%f&quot;,...

Ошибка округления при использовании float или double
Да-да, избитая тема. Понятно, что любое нецелое число может быть представленно в современных...


Искать еще темы с ответами

Или воспользуйтесь поиском по форуму:
19
Ответ Создать тему
КиберФорум - форум программистов, компьютерный форум, программирование
Powered by vBulletin
Copyright ©2000 - 2024, CyberForum.ru