PHP
var_dump(intval(0.58 * 100));
Правильный результат-57, а не 58.
Операции с плавающей запятой
На самом деле эти результаты не являются языковыми ошибками, а связаны с принципом реализации языка. Все номера JS унифицированы как число, включая формирование. На самом деле, все они являются двойными типами.
PHP различает int и float. Независимо от того, на каком языке, пока используются операции с плавающей запятой, существуют аналогичные проблемы, на которые мы должны обращать внимание при их использовании.
Пояснение: Если вы используете PHP +-*/для вычисления чисел с плавающей запятой, вы можете столкнуться с некоторыми ошибками в вычислениях, такими как echo intval (0,58*100) выше; он будет печатать 57 вместо 58, что на самом деле является ошибкой, из-за которой нижний двоичный файл компьютера не может точно представлять числа с плавающей запятой. Это межъязыковое, и я также сталкиваюсь с этим с python. Проблема. Таким образом, в основном большинство языков предоставляют библиотеку классов или библиотеку функций для точного вычисления. Например, в PHP есть библиотека высокоточных функций BC. Позже я представлю некоторые часто используемые высокоточные функции BC.
Вернемся к вопросу 57,58 выше.
Почему вывод 57? Ошибка PHP?
Чтобы понять это, сначала нам нужно знать представление чисел с плавающей запятой (IEEE 754).:
- Числа с плавающей запятой, например, 64-разрядной длины (двойная точность), представлены 1-битными символьными битами (E), 11 экспоненциальными битами (Q), 52-битной мантиссой (M).
- Бит символа: Старший бит представляет положительные и отрицательные данные, 0 представляет положительное число, а 1 представляет отрицательное число.
- Экспоненциальные биты: Мощность данных в нижней части 2 представлена кодом смещения.
- Число: Значимое число после десятичной точки данных.
Ключевым моментом здесь является представление десятичной дроби в двоичной системе. Вы можете рассказать Байду о том, как десятичная дробь выражается в двоичной системе. Я не буду повторять это здесь. Наш ключевой момент состоит в том, чтобы понять, что 0,58-это бесконечное значение для двоичной системы (приведенное ниже число опускает подразумеваемый 1)..
Двоичное представление 0,58 в основном (52 бита) 00101000111011100001011011011010101110000101101000101010101011110100011110,57. Двоичное представление 0.58 в основном (52 бита) 0010001111010111000010110100011110.11110, и двоичное представление обоих: www.jb51.net если только вычисляется по 52 битам.
0,58 – > 0,579999999999999999999960,57 – > 0,569999999999999999999999 что касается конкретного умножения с плавающей запятой 0,58 * 100, мы не считаем, что подробно, интересно можно увидеть (с плавающей запятой), мы расплывчаты с точки зрения ментальной арифметики..999999999
Затем вы вводите его, естественно, это 57.
Итак, ключ к этой проблеме заключается в следующем: “Кажется, что у вас бесконечные десятичные числа, но в двоичном представлении компьютера у вас бесконечные десятичные числа.”
Так что не думайте, что это ошибка в PHP больше. Вот что это такое..
PHP с плавающей запятой в +-*%/Существует неточная проблема
Продолжайте просматривать фрагмент кода:
$a = 0.1; $b = 0.7; var_dump(($a + $b) == 0.8); // false
Печатное значение-логическое значение false
Почему? Руководство по PHP содержит следующие предупреждения для чисел с плавающей запятой:
Предупреждение
Точность с плавающей Запятой
Очевидно, что простые десятичные дроби, такие как 0,1 или 0,7, не могут быть преобразованы во внутренние двоичные форматы без потери некоторой точности. Это может привести к запутанным результатам: этаж ((0.1 + 0.7) * 10), например, обычно возвращает 7 вместо 8, как ожидалось, потому что внутреннее представление результата на самом деле похоже на 7.99999999….
Это связано с тем, что невозможно точно выразить определенные десятичные дроби бесконечными цифрами. Например, одна треть десятичной системы становится 0,3333333….
Поэтому никогда не верьте, что результат с плавающей запятой точен до последней точки, и никогда не сравнивайте, равны ли два числа с плавающей запятой. Если действительно требуется более высокая точность, следует использовать математические функции произвольной точности или функции GMP.
Поэтому приведенную выше формулу следует переписать следующим образом
$a = 0.1; $b = 0.7; var_dump(bcadd($a,$b,2) == 0.8); // true
Обычно используемые высокоточные функции заключаются в следующем:
- Bcadd – Добавляет две цифры высокой точности
- Bccomp – Сравнение двух высокоточных чисел, возврат – 1, 0, 1
- Bcdiv – деление двух цифр высокой точности
- Bcmod-Поиск Высокоточного Цифрового Остатка
- Bcmul – Умножение двух чисел высокой точности
- Bcpow-Поиск Высокоточного Цифрового Умножителя
- Bcpowmod – высокоточный цифровой модуль умножения, очень распространенный в теории чисел
- Масштаб BC — Настройте десятичное число по умолчанию, которое эквивалентно “масштаб=” в Linux BC
- Bcsqrt-Поиск Цифровых Квадратных Корней Высокой Точности
- Bcsub – Вычитание Двух Чисел Высокой Точности
Библиотека функций высокой точности BC включает в себя: добавление, сравнение, деление, вычитание, избыточность, кратность, мощность, настройка количества десятичных знаков по умолчанию, квадрат. Эти функции полезны, когда речь заходит о денежных расчетах, таких как расчеты цен для электронной коммерции.
/**
* Comparison of Two High Precision Numbers
*
* @access global
* @param float $left
* @param float $right
*@ The exact decimal point number of param int $scale
*
*@ Return int $left== $right returns 0 | $left < $right returns - 1 | $left > $right returns 1
*/
var_dump(bccomp($left=4.45, $right=5.54, 2));
// -1
/**
* Addition of Two High Precision Numbers
*
* @access global
* @param float $left
* @param float $right
*@ The exact decimal point number of param int $scale
*
* @return string
*/
var_dump(bcadd($left=1.0321456, $right=0.0243456, 2));
//1.05
/**
* Subtraction of Two High Precision Numbers
*
* @access global
* @param float $left
* @param float $right
*@ The exact decimal point number of param int $scale
*
* @return string
*/
var_dump(bcsub($left=1.0321456, $right=3.0123456, 2));
//-1.98
/**
* Two High Precision Dividing Numbers
*
* @access global
* @param float $left
* @param float $right
*@ The exact decimal point number of param int $scale
*
* @return string
*/
var_dump(bcdiv($left=6, $right=5, 2));
//1.20
/**
* Multiplication of Two High Precision Numbers
*
* @access global
* @param float $left
* @param float $right
*@ The exact decimal point number of param int $scale
*
* @return string
*/
var_dump(bcmul($left=3.1415926, $right=2.4569874566, 2));
//7.71
/**
* Setting the decimal point number of BC function
*
* @access global
*@ The exact decimal point number of param int $scale
*
* @return void
*/
bcscale(3);
var_dump(bcdiv('105', '6.55957'));
//php7.1 16Выше приведено все содержание этой статьи. Я надеюсь, что это будет полезно для изучения каждого, и я надеюсь, что вы будете больше поддерживать разработчика.