Странное поведение Golang при преобразовании float в int

У меня есть следующий код в golang:

var fnum float32 = 99999999;
var inum int32 = int32(fnum);
fmt.Println(inum); // This prints out 100000000

Почему 99999999 заменено на 100000000? Я не думаю, что вышел за пределы как float32, так и int32, поэтому не уверен, почему это происходит.

float32 имеет точность 6 (или 7) значащих цифр, что означает, что все, что выше, может быть потеряно. Это не специфично для Go, каждый язык, реализующий IEEE754, будет вести себя одинаково.
zerkms 23.12.2020 02:30

32-битное число с плавающей запятой имеет 24 бита мантиссы, что дает вам до 16777216 точных целых чисел, ваше 99999999 больше, поэтому происходит округление. Однако это странно, так как при приведении к округлению int чаще встречается ...

Spektre 23.12.2020 09:27

@Spektre не «округляется» при преобразовании в int, а во время присваивания var fnum float32 = 99999999;. Когда происходит int32(fnum) - точность уже потеряна.

zerkms 25.12.2020 01:17

@zerkms «приведение к типу int» происходит при преобразовании 99999999 в часть мантиссы float, поскольку мантисса - это 24-битное целое число !!! Так что да, это происходит в строке var fnum float32 = 99999999; во время компиляции (если у вас нет интерпретирующей среды), мантисса должна содержать 12499999 (поскольку это 24-битные старшие значащие биты 99999999), однако вы утверждаете, что ваш номер 100000000, что странно, но может быть просто округление во время печати, попробуйте напечатать с полной точностью, например, заставить печатать 10 знаков после запятой после ., и вы должны увидеть что-то вроде 9999999?.??????????

Spektre 06.01.2021 10:34

@Spektre float32 не может представлять 99999999. 100000000 - ближайшее представимое значение (отдельно на 1). binaryconvert.com/… Мантисса 12499999 приводит к 9.9999992E7 (разделено на 7) binaryconvert.com/result_float.html?hexadecimal=4CBEBC1F

zerkms 06.01.2021 10:54
Создание API ввода вопросов на разных языках программирования (Python, PHP, Go и Node.js)
Создание API ввода вопросов на разных языках программирования (Python, PHP, Go и Node.js)
API ввода вопросов - это полезный инструмент для интеграции моделей машинного обучения, таких как ChatGPT, в приложения, требующие обработки...
1
5
363
1
Перейти к ответу Данный вопрос помечен как решенный

Ответы 1

Ответ принят как подходящий

(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.

Другие вопросы по теме