Преобразование из Float в CGFloat в Swift - PullRequest
0 голосов
/ 02 мая 2018

Я конвертировал Float => CGFloat, и это дало мне следующий результат. Почему после преобразования он отображается как «0.349999994039536», но отлично работает с Double => CGFloat?

let float: Float = 0.35
let cgFloat = CGFloat(float)
print(cgFloat)
// 0.349999994039536

let double: Double = 0.35
let cgFloat = CGFloat(double)
print(cgFloat)
// 0.35

1 Ответ

0 голосов
/ 02 мая 2018

Как преобразование «.35» в float, так и преобразование «.35» в double дают значение, отличное от .35, поскольку в форматах с плавающей запятой используется двоичная база, поэтому точное математическое значение должно быть аппроксимируется с использованием степеней двух (в данном случае отрицательных степеней двух).

Поскольку формат float использует меньше битов, его результат менее точен и, в этом случае, менее точен. Значение float равно 0,3499999940395355224609375, а значение double равно 0,34999999999999997779553950749686919152736663818359375.

Я не полностью знаком со Swift, но подозреваю, что алгоритм, который он использует для преобразования CGFloat в десятичную (с параметрами по умолчанию), выглядит примерно так:

  • Создает фиксированное количество десятичных цифр с правильным округлением от фактического значения CGFloat до количества цифр, а затем подавляет любые завершающие нули. Например, если точное математическое значение равно 0,34999999999999997… и форматирование использует 15 значащих цифр, промежуточный результат будет «0,350000000000000», а затем он будет закорочен до «0,35».

Способ работы с float и double:

  • При преобразовании в double, .35 становится 0,34999999999999997779553950749686919152736663818359375. При печати с использованием вышеуказанных методов результат будет «0,35».
  • При преобразовании в float, .35 становится 0,3499999940395355224609375. При печати с использованием вышеуказанного метода, результат «0.349999994039536».

Таким образом, значения float и double отличаются от .35, но форматирование для печати не использует достаточно цифр, чтобы показать отклонение для значения double, в то время как оно использует достаточно цифр, чтобы показать отклонение для значения float.

...