Як Lua обробляє як цілі, так і плаваючі числа?


11

Наскільки я пам'ятаю себе програмуванням, мене навчали не порівнювати числа з плаваючою комою для рівності. Тепер, читаючи Програмування в Луї про numberтип Луа , я виявив наступне:

Тип числа представляє реальні числа з плаваючою комою з подвійною точністю. Lua не має цілого типу, оскільки він не потребує. Існує широко поширене помилкове уявлення про арифметичні помилки з плаваючою комою, і деякі люди бояться, що навіть простий приріст може стати дивним з числами з плаваючою комою. Справа в тому, що, коли ви використовуєте подвійний для представлення цілого числа, взагалі немає помилки округлення (якщо тільки число не перевищує 100 000 000 000 000). Зокрема, число Lua може представляти будь-яке довге ціле число без проблем округлення. Більш того, більшість сучасних процесорів виконують арифметику з плаваючою комою так само швидко, як і (або навіть швидше, ніж) цілу арифметику.

Це правда для всіх мов? В основному, якщо ми не виходимо за межі плаваючої точки в парних, ми в безпеці в цілій арифметиці? Або, щоб більше відповідати заголовку запитання, чи є щось особливе, що робить Lua зі своїм numberтипом, щоб він працював чудово як з цілим числом, так і з плаваючою точкою?



@JoonasPulakka дякую, це досить цінне доповнення.
Петро Абдулін

Відповіді:


11

Луа стверджує, що числа з плаваючою комою можуть представляти цілі числа так само, як і цілі типи, і я схильний погодитися. Немає чіткого представлення дробової числової частини, з якою слід мати справу. Незалежно від того, зберігаєте ви ціле число у цілому типі чи зберігаєте його в мантісі числа з плаваючою точкою, результат такий же: це ціле число може бути представлено точно, доки ви не перевищите кількість бітів у мантісі , + 1 біт в експоненті.

Звичайно, якщо ви намагаєтесь зберегти фактичне число з плаваючою комою (наприклад, 12.345) у поданні з плаваючою комою, усі ставки будуть вимкнені, тому у вашій програмі має бути зрозуміло, що число справді є справжнім цілим числом, яке не переповнює mantissa, щоб трактувати це як фактичне ціле число (тобто щодо порівняння рівності).

Якщо вам потрібна більш ціла точність, ніж це, ви завжди можете використовувати бібліотеку довільної точності .

Подальше читання
Яке максимальне значення числа в Луа?


А як же їх другий аргумент, тобто, що плаваюча точка є такою ж швидкою чи швидшою, ніж ціла арифметика в сучасних процесорах? Для мене звучить сумнівно, навіть коли використовуються числа з плаваючою комою для виконання цілої арифметики.
Андрес Ф.

2
@AndresF. Я не бачу, як це швидше, якщо ви не усунете команду, використовуючи один числовий тип замість двох.
Роберт Харві

Домовились. Це не має для мене сенсу. Цікаво, чи це виведено з контексту ...
Андрес Ф.

1
Досить великі цілі числа не можуть бути точно збережені в об'єкті з плаваючою комою. 64-бітний doubleмає близько 51 біт мантіси; непарні цілі числа, що перевищують приблизно 2 ** 51, матимуть помилки округлення. 64-бітове ціле число може точно зберігати великі цілі значення, оскільки воно не виділяє жодних бітів на експонент.
Кіт Томпсон

@KeithThompson: Я вважав, що це мається на увазі у моїй відповіді, коли я сказав, що "зберігається в мантісі". Однак я відредагую відповідь, щоб уточнити.
Роберт Харві

6

Парні парні запам'ятовуються як мантіса і експонент. Додаткову інформацію див. У форматі . В основному всі числа мають форму: mantissa * 2 exponent . Для будь-якого цілого числа, меншого за 2 52 , показник буде дорівнювати нулю, що робить мантісу біт на біт еквівалентом 52-бітного цілого числа, що не підписується. Окремий біт знаків використовується для позначення від’ємних чисел.

Насправді навіть деякі цілі числа, що перевищують 2 52, можуть бути точно представлені до тих пір, поки всі цифри, що минули 52- е, - нулі. Також деякі фракції, як 0,5, можуть бути представлені точно. Лише тоді, коли частка постійно повторюється (як 1/3) у базі 2, або в іншому випадку потрібно занадто багато біт, повз точку радіації, ви втрачаєте точність.


Це не через постійне повторення десяткових знаків. Це тому, що багато десяткових (базових десяти) чисел не можуть бути представлені точно як два.
Роберт Харві

3
У підставі 2, число , які не можуть бути представлені точно буде безперервно повторюватися. Наприклад, 0,1 десяткової стає 0,0 (0011) у двійковій формі, при цьому 0011 постійно повторюється.
Карл Білефельдт

3
Так, саме. Але не повторюється в базі 10. Повторення в базі 2.
Роберт Харві
Використовуючи наш веб-сайт, ви визнаєте, що прочитали та зрозуміли наші Політику щодо файлів cookie та Політику конфіденційності.
Licensed under cc by-sa 3.0 with attribution required.