Разница между преобразованием двоичного файла в float в C # и C / C

#c# #c #c #.net

#c# #c #c #.net

Вопрос:

При преобразовании двоичного числа в C / C и C # мы получаем 2 разных результата путем его округления. Например — давайте возьмем 1000010000010110110000010111111 , в C # — мы получили бы, 34.84448 в то время как мы получили бы 34.844479 , почему это незначительное различие? Преобразование в C#:

 float f = System.BitConverter.ToSingle(bytearray,0);
//bytearray is an array that contains our binary number
  

в C :

 int a = 1108041919; //The number that is being represented
float f = *(float *)amp;a;
  

Комментарии:

1. Они имеют точно такое же значение, просто их строковые представления отличаются.

2. Это одно и то же число, просто округленное до другого количества цифр. В чем именно заключается ваш вопрос?

3. @Jose Да, это так, я этого не заметил, спасибо

4. Кстати, ваш код на C нарушает строгое наложение псевдонимов (и, следовательно, поведение в соответствии со стандартом не определено).

5. Верно, вы можете захотеть отредактировать вопрос, чтобы сделать это намного понятнее. Звучит так, как будто вы думаете, что результат преобразования в float значение дает разные результаты на разных платформах.

Ответ №1:

Существует много способов однозначно представить одно и то же значение с плавающей запятой в десятичной форме. Например, вы можете добавить произвольное количество нулей после точного вывода (обратите внимание, что поскольку каждая степень двойки имеет десятичное представление конечной длины, то же самое относится и к каждому числу с плавающей запятой).

Критерий «когда я могу прекратить печатать дополнительные цифры» обычно выбирается как «вы можете прекратить печатать дополнительные цифры, когда вы получите точно такое же значение обратно, если вы снова преобразуете десятичный вывод в формат float». Короче говоря: ожидается, что вывод float «обходится».

Если вы проанализируете десятичные представления 34.844479 и 34.84448 , вы обнаружите, что они оба преобразуются обратно в значение с плавающей запятой 0x420b60bf или 01000010000010110110000010111111 . Таким образом, обе эти строки представляют одно и то же число с плавающей запятой. (Источник: Попробуйте сами на https://www.h-schmidt.net/FloatConverter/IEEE754.html )

Ваш вопрос сводится к «Почему разные библиотеки среды выполнения выводят разные значения для одного и того же значения с плавающей точкой?», на что следует ответить: «обычно библиотека сама решает, когда прекратить печать цифр, они не обязаны останавливаться на минимуме». Пока вы можете получить тот же float обратно при повторном анализе, библиотека выполнила свою работу.

Если вы хотите видеть точно такие же десятичные строки, вы можете добиться этого с помощью соответствующих параметров форматирования.

Ответ №2:

Поскольку значение одно и то же, мы могли бы предположить, что функция печати, которая обрабатывает значение, может быть незначительной разницей там 🙂

Комментарии:

1. @Martin Здесь никакого преобразования не происходит. 1000010000010110110000010111111 и 34.844478607177734375 оба являются одним и тем же float, просто в разных представлениях. Преобразование не происходит, если я печатаю его как 0x420b60bf либо.

2. @Martin То, что отладчик что-то показывает, не означает, что это правда. Насколько вам известно, отладчик использует точно такую же функцию для «печати» значения в виде пользовательского кода.

3. @Martin: Вполне разумно рассматривать «показанный в отладчике» как «функцию печати», IMO. Ответ здесь заключается в утверждении, что значение одно и то же, и преобразование в текстовую форму здесь является разницей, в отличие от преобразования «двоичного файла в float», заявленного в вопросе.

4. Еще один случай, когда сборщики придирок ухватились за невинный комментарий, пытаясь показать, какие они умные. Молодцы, вы все такие умные, указываете на то, что не имеет ничего общего с тем, что я сказал

5. @Martin: Когда два человека независимо друг от друга неправильно понимают вас одинаково, вам следует подумать, что, возможно, вы не совсем ясно выразились. Мне все еще кажется, что проблема заключается в преобразовании числа с плавающей запятой в текстовое представление, о чем говорится и в этом ответе. Вы все еще убеждены, что ответ неверен? (Если вы не имеете в виду то, что, как я думал, вы имели в виду в первом комментарии, то я все еще не знаю, что вы имели в виду.)