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

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

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

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

итак немного теории, все мы знаем, что 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
Эксперт
39485 / 9562 / 3019
Регистрация: 12.04.2006
Сообщений: 41,671
Блог
06.12.2017, 16:57
Ответы с готовыми решениями:

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

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

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

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

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

Добавлено через 1 минуту
Вы не сможете найти такую комбинацию битов в объекте типа float, чтобы результат его интерпретации оказался вточности равен 44.47647. Довольно типичная проблема при переходе между системами счисления.
0
0 / 0 / 0
Регистрация: 26.01.2016
Сообщений: 45
06.12.2017, 17:55  [ТС]
Цитата Сообщение от Mirmik Посмотреть сообщение
Вы не сможете найти такую комбинацию битов в объекте типа float,
да я и не спорю, но у нас значение числа в 4х байтах не может быть равно числу в 8 байтах, и уж темболее заполненным.
и я никак не возьму в толк, почему при касте влота в дабл, я получаю то-же значение, хотя поидее там должны быть нули.
0
techpriest
 Аватар для Mirmik
634 / 213 / 57
Регистрация: 27.02.2014
Сообщений: 1,180
06.12.2017, 18:29
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
зомбяк
 Аватар для TRam_
1585 / 1219 / 345
Регистрация: 14.05.2017
Сообщений: 3,940
06.12.2017, 18:31
но у нас значение числа в 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
 Аватар для Mirmik
634 / 213 / 57
Регистрация: 27.02.2014
Сообщений: 1,180
06.12.2017, 18:34
Проблема в том, что вы думаете в десятичной системе счисления. Числа, записанные в десятичной системе счисления не всегда красиво выглядят в двоичной и наоборот.

Как вам, например, (double)0.9:
0011111111101100110011001100110011001100 110011001100110011001101
0
зомбяк
 Аватар для TRam_
1585 / 1219 / 345
Регистрация: 14.05.2017
Сообщений: 3,940
06.12.2017, 18:35
Только я уверен что ни в *(reinterpret_cast<float *>(&b)), ни в a2 никакого значения наподобие 44.47647 не будет. Потому что https://ru.wikipedia.org/wiki/... й_точности vs https://ru.wikipedia.org/wiki/... й_точности - имеют ну совершенно разное разбиение по битам.
0
techpriest
 Аватар для Mirmik
634 / 213 / 57
Регистрация: 27.02.2014
Сообщений: 1,180
06.12.2017, 18:55
При сранении бинарного представления надо помнить, что мантиса double сдвинута относительно float, а также не забыть про little endian
0
Эксперт .NET
 Аватар для Rius
13025 / 7590 / 1661
Регистрация: 25.05.2015
Сообщений: 23,090
Записей в блоге: 14
06.12.2017, 19:51
Цитата Сообщение от Mimik_fc7 Посмотреть сообщение
Вопрос в том, почему они равны?
Просто так совпало. Вы выбрали числа до и после приведения типа.

Проверить двоичное и 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  [ТС]
Цитата Сообщение от TRam_ Посмотреть сообщение
А чтоб "по идее там должны быть нули" - сделай вот так:
и они будут равны =)))
0
Эксперт .NET
 Аватар для Rius
13025 / 7590 / 1661
Регистрация: 25.05.2015
Сообщений: 23,090
Записей в блоге: 14
07.12.2017, 09:11
Вы вовсе не float с double сравниваете.
Перед сравнением, оба операнда приводятся к одинаковому типу. Точнее один, который float, приводится к double.
При приведении от float к double, 44.4764709 превращается в 44.476470947265625.
Но это число у вас уже есть и, очевидно, получено оно именно таким приведением типа.
Поэтому операнды и в двоичном виде эквивалентны.

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

C++
1
2
3
44.47647f
double 0100000001000110001111001111110100000000000000000000000000000000
float  01000010001100011110011111101000
Посмотрим подробнее:
C++
1
2
3
знак    экспонента          мантиса
0       10000000100        0110001111001111110100000000000000000000000000000000
0       10000100           01100011110011111101000
Как видите экспоненты записываются в смещенном коде (они равны).
Мантисы задают дробную часть и также равны.
0
Надоела реклама? Зарегистрируйтесь и она исчезнет полностью.
inter-admin
Эксперт
29715 / 6470 / 2152
Регистрация: 06.03.2009
Сообщений: 28,500
Блог
07.12.2017, 12:17
Помогаю со студенческими работами здесь

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

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

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

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

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


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

Или воспользуйтесь поиском по форуму:
19
Ответ Создать тему
Новые блоги и статьи
PhpStorm 2025.3: WSL Terminal всегда стартует в ~
and_y87 14.12.2025
PhpStorm 2025. 3: WSL Terminal всегда стартует в ~ (home), игнорируя директорию проекта Симптом: После обновления до PhpStorm 2025. 3 встроенный терминал WSL открывается в домашней директории. . .
Access
VikBal 11.12.2025
Помогите пожалуйста !! Как объединить 2 одинаковые БД Access с разными данными.
Новый ноутбук
volvo 07.12.2025
Всем привет. По скидке в "черную пятницу" взял себе новый ноутбук Lenovo ThinkBook 16 G7 на Амазоне: Ryzen 5 7533HS 64 Gb DDR5 1Tb NVMe 16" Full HD Display Win11 Pro
Музыка, написанная Искусственным Интеллектом
volvo 04.12.2025
Всем привет. Некоторое время назад меня заинтересовало, что уже умеет ИИ в плане написания музыки для песен, и, собственно, исполнения этих самых песен. Стихов у нас много, уже вышли 4 книги, еще 3. . .
От async/await к виртуальным потокам в Python
IndentationError 23.11.2025
Армин Ронахер поставил под сомнение async/ await. Создатель Flask заявляет: цветные функции - провал, виртуальные потоки - решение. Не threading-динозавры, а новое поколение лёгких потоков. Откат?. . .
Поиск "дружественных имён" СОМ портов
Argus19 22.11.2025
Поиск "дружественных имён" СОМ портов На странице: https:/ / norseev. ru/ 2018/ 01/ 04/ comportlist_windows/ нашёл схожую тему. Там приведён код на С++, который показывает только имена СОМ портов, типа,. . .
Сколько Государство потратило денег на меня, обеспечивая инсулином.
Programma_Boinc 20.11.2025
Сколько Государство потратило денег на меня, обеспечивая инсулином. Вот решила сделать интересный приблизительный подсчет, сколько государство потратило на меня денег на покупку инсулинов. . . .
Ломающие изменения в C#.NStar Alpha
Etyuhibosecyu 20.11.2025
Уже можно не только тестировать, но и пользоваться C#. NStar - писать оконные приложения, содержащие надписи, кнопки, текстовые поля и даже изображения, например, моя игра "Три в ряд" написана на этом. . .
Мысли в слух
kumehtar 18.11.2025
Кстати, совсем недавно имел разговор на тему медитаций с людьми. И обнаружил, что они вообще не понимают что такое медитация и зачем она нужна. Самые базовые вещи. Для них это - когда просто люди. . .
Создание Single Page Application на фреймах
krapotkin 16.11.2025
Статья исключительно для начинающих. Подходы оригинальностью не блещут. В век Веб все очень привыкли к дизайну Single-Page-Application . Быстренько разберем подход "на фреймах". Мы делаем одну. . .
КиберФорум - форум программистов, компьютерный форум, программирование
Powered by vBulletin
Copyright ©2000 - 2025, CyberForum.ru