У меня есть следующий код в golang:
var fnum float32 = 99999999;
var inum int32 = int32(fnum);
fmt.Println(inum); // This prints out 100000000
Почему 99999999 заменено на 100000000? Я не думаю, что вышел за пределы как float32, так и int32, поэтому не уверен, почему это происходит.
32-битное число с плавающей запятой имеет 24 бита мантиссы, что дает вам до 16777216
точных целых чисел, ваше 99999999
больше, поэтому происходит округление. Однако это странно, так как при приведении к округлению int чаще встречается ...
@Spektre не «округляется» при преобразовании в int, а во время присваивания var fnum float32 = 99999999;
. Когда происходит int32(fnum)
- точность уже потеряна.
@zerkms «приведение к типу int» происходит при преобразовании 99999999
в часть мантиссы float
, поскольку мантисса - это 24-битное целое число !!! Так что да, это происходит в строке var fnum float32 = 99999999;
во время компиляции (если у вас нет интерпретирующей среды), мантисса должна содержать 12499999
(поскольку это 24-битные старшие значащие биты 99999999
), однако вы утверждаете, что ваш номер 100000000
, что странно, но может быть просто округление во время печати, попробуйте напечатать с полной точностью, например, заставить печатать 10 знаков после запятой после .
, и вы должны увидеть что-то вроде 9999999?.??????????
@Spektre float32
не может представлять 99999999
. 100000000
- ближайшее представимое значение (отдельно на 1). binaryconvert.com/… Мантисса 12499999
приводит к 9.9999992E7
(разделено на 7) binaryconvert.com/result_float.html?hexadecimal=4CBEBC1F
(IEEE 754) 32-битное число с плавающей запятой представляет действительные значения в форме
value = (−1)^sign × 2^e × (1 + 2^−1 b[22] + 2^−2 b[21] + ... + 2^−23 b[0])
где «e» — целочисленный показатель степени от −126 до +127, а «b[22], ..., b[0]» составляют биты мантиссы.
Ясно, что это представление ограничено, не все действительные числа могут быть точно выражены. Когда дело доходит до целых чисел, наименьшее целое число, которое не может быть точно представлено как float32, равно 2^24 + 1 = 16777217. В частности, в этот момент показатель степени равен 2^24, но с наименьшим значащим членом, равным 2^−23b[ 0], нечетные целые числа (значение % 2) ≠ 0 выше 2^24 не могут быть точно представлены.
Точно так же для значения 99999999 коэффициент степени равен 2 ^ 26, а целые числа выше 2 ^ 26 с (значение % 8) ≠ 0 не могут быть точно представлены. Ближайшие представимые значения float32 к 99999999 — это 99999992 и 100000000.
float32
имеет точность 6 (или 7) значащих цифр, что означает, что все, что выше, может быть потеряно. Это не специфично для Go, каждый язык, реализующий IEEE754, будет вести себя одинаково.