#c# #floating-point
#c# #с плавающей запятой
Вопрос:
При преобразовании двоичных данных в значения с плавающей запятой с использованием String#unpack
метода ruby я получаю следующие результаты:
[0x7d, 0xe8, 0x80, 0xc5].map(amp;:chr).join.unpack('e')[0]
# => -4125.06103515625
Это считается правильным результатом.
Используя BitConverter.ToSingle
метод C #, я получаю следующий результат:
var firstVal = BitConverter.ToSingle(new byte[] {0x7d, 0xe8, 0x80, 0xc5}, 0);
// firstVal: -4125.061
Таким образом, кажется, что значение каким-то образом усекается.
Есть ли способ извлечь правильное значение (как в ruby
примере) из двоичного представления?
Комментарии:
1. Как вы печатаете значение?
2.
Console.WriteLine(((double)firstVal).ToString("R"));
выводит то же значение, что и ruby.
Ответ №1:
Насколько я помню, Ruby имеет только один тип с плавающей запятой, и это float с двойной точностью. Таким образом, тип значения вашего выражения ruby — это значение с плавающей запятой двойной точности, аналог которого в C # — «double». Так что, если вы хотите получить точно такое же число, вы можете сделать это (но я не уверен, что это действительно имеет смысл, см. Комментарий @xanatos):
var firstVal = (double) BitConverter.ToSingle(new byte[] {0x7d, 0xe8, 0x80, 0xc5}, 0);
// firstVal is -4125.06103515625
Комментарии:
1. Нужно задаться вопросом, почему в документации указано, что строка
'e'
формата будет возвращать число с плавающей запятой одинарной точности… с документацией проблемы снова и снова…2. @InBetween Я думаю, что в нем указано, что возвращаемое значение равно Float (единственный тип ruby с плавающей запятой), но формат «e» означает, что массив байтов следует рассматривать как содержащий одинарную точность с плавающей запятой (поэтому имеет 4 байта, а не 8, как double)
3. о, лол. Я связал «строку формата» с выводом, а не с вводом. Думаю, это имеет смысл…