Pułapki liczb zmiennoprzecinkowych. Adam Sawicki asawicki.info

Podobne dokumenty
Liczby rzeczywiste są reprezentowane w komputerze przez liczby zmiennopozycyjne. Liczbę k można przedstawid w postaci:

Kod IEEE754. IEEE754 (1985) - norma dotycząca zapisu binarnego liczb zmiennopozycyjnych (pojedynczej precyzji) Liczbę binarną o postaci

Pracownia Komputerowa wykład VI

Podstawy Informatyki. Metalurgia, I rok. Wykład 3 Liczby w komputerze

Zwykle liczby rzeczywiste przedstawia się w notacji naukowej :

Liczby zmiennoprzecinkowe i błędy

Podstawy Informatyki. Inżynieria Ciepła, I rok. Wykład 5 Liczby w komputerze

Metody numeryczne Technika obliczeniowa i symulacyjna Sem. 2, EiT, 2014/2015

Podstawy Informatyki

Wprowadzenie do metod numerycznych. Krzysztof Patan

Wprowadzenie do architektury komputerów systemy liczbowe, operacje arytmetyczne i logiczne

Wielkości liczbowe. Wykład z Podstaw Informatyki dla I roku BO. Piotr Mika

Wielkości liczbowe. Wykład z Podstaw Informatyki. Piotr Mika

Pracownia Komputerowa wyk ad VI

Reprezentacja stałoprzecinkowa. Reprezentacja zmiennoprzecinkowa zapis zmiennoprzecinkowy liczby rzeczywistej

Wstęp do programowania

Obliczenia Naukowe. O arytmetyce komputerów, Czyli jak nie dać się zaskoczyć. Bartek Wilczyński 29.

Kodowanie liczb. Reprezentacja liczb całkowitych. Standard IEEE 754. dr inż. Jarosław Forenc

Teoretyczne Podstawy Informatyki

Technologie Informacyjne Wykład 4

Przedmiot: Urządzenia techniki komputerowej Nauczyciel: Mirosław Ruciński

Arytmetyka stało i zmiennoprzecinkowa

Informatyka 1. Wykład nr 5 ( ) Politechnika Białostocka. - Wydział Elektryczny. dr inŝ. Jarosław Forenc

Met Me ody numer yczne Wykład ykład Dr inż. Mic hał ha Łan Łan zon Instyt Ins ut Elektr Elektr echn iki echn i Elektrot Elektr echn olo echn

ARCHITEKTURA KOMPUTERÓW Liczby zmiennoprzecinkowe

Architektura komputerów Reprezentacja liczb. Kodowanie rozkazów.

BŁĘDY OBLICZEŃ NUMERYCZNYCH

Pracownia Komputerowa wykład IV

Pracownia komputerowa. Dariusz Wardecki, wyk. VI

Naturalny kod binarny (NKB)

Architektura komputerów

Dokładność obliczeń numerycznych

Zestaw 3. - Zapis liczb binarnych ze znakiem 1

SYSTEMY LICZBOWE. SYSTEMY POZYCYJNE: dziesiętny (arabski): 0, 1, 2, 3, 4, 5, 6, 7, 8, 9 rzymski: I, II, III, V, C, M

Systemy liczbowe. 1. Przedstawić w postaci sumy wag poszczególnych cyfr liczbę rzeczywistą R = (10).

Dr inż. Grażyna KRUPIŃSKA. D-10 pokój 227 WYKŁAD 2 WSTĘP DO INFORMATYKI

Metody numeryczne II. Reprezentacja liczb

Programowanie. programowania. Klasa 3 Lekcja 9 PASCAL & C++

DYDAKTYKA ZAGADNIENIA CYFROWE ZAGADNIENIA CYFROWE

Wstęp do programowania. Reprezentacje liczb. Liczby naturalne, całkowite i rzeczywiste w układzie binarnym

Typ użyty w deklaracji zmiennej decyduje o rodzaju informacji, a nazwa zmiennej symbolicznie opisuje wartość.

Reprezentacja symboli w komputerze. Liczby całkowite i zmiennoprzecinkowe. Programowanie Proceduralne 1

Arytmetyka binarna - wykład 6

2018 Marcin Kukliński. Niesforne bity i bajty

Pracownia Komputerowa wyk ad IV

Podstawy Programowania ELEMENTY PROGRAMU i TYPY DANYCH

Wstęp do Informatyki. Reprezentacja liczb w komputerze Arytmetyka stało- i zmiennoprzecinkowa Przechowywanie danych pliki i foldery

Algorytmy i struktury danych. wykład 1

Arytmetyka zmiennoprzecinkowa wer. 5

Język C część 1. Sformułuj problem Zanalizuj go znajdź metodę rozwiązania (pomocny może byd algorytm) Napisz program Uruchom i przetestuj czy działa

1 Podstawy c++ w pigułce.

ARCHITEKTURA SYSTEMÓW KOMPUTEROWYCH

Podstawy Informatyki. Wykład 2. Reprezentacja liczb w komputerze

LICZBY ZMIENNOPRZECINKOWE

Adam Korzeniewski p Katedra Systemów Multimedialnych

Informatyka 1. Wykład nr 4 ( ) Plan wykładu nr 4. Politechnika Białostocka. - Wydział Elektryczny

Samodzielnie wykonaj następujące operacje: 13 / 2 = 30 / 5 = 73 / 15 = 15 / 23 = 13 % 2 = 30 % 5 = 73 % 15 = 15 % 23 =

ARCHITEKRURA KOMPUTERÓW Kodowanie liczb ze znakiem

Dodatek do Wykładu 01: Kodowanie liczb w komputerze

Adam Korzeniewski p Katedra Systemów Multimedialnych

Podstawy programowania C. dr. Krystyna Łapin

4 Standardy reprezentacji znaków. 5 Przechowywanie danych w pamięci. 6 Literatura

dr inż. Jarosław Forenc

Wstęp do informatyki- wykład 1 Systemy liczbowe

Pozycyjny system liczbowy

Stan wysoki (H) i stan niski (L)

Podstawy programowania. 1. Operacje arytmetyczne Operacja arytmetyczna jest opisywana za pomocą znaku operacji i jednego lub dwóch wyrażeń.

Arytmetyka komputerów

Systemy zapisu liczb.

Arytmetyka stało- i zmiennoprzecinkowa. 1. Informacje wstępne

Wykład I. Programowanie. dr inż. Janusz Słupik. Gliwice, Wydział Matematyki Stosowanej Politechniki Śląskiej. c Copyright 2014 Janusz Słupik

Java Podstawy. Michał Bereta

ARYTMETYKA BINARNA. Dziesiątkowy system pozycyjny nie jest jedynym sposobem kodowania liczb z jakim mamy na co dzień do czynienia.

Python wstęp do programowania dla użytkowników WCSS

Powtórka algorytmów. Wprowadzenie do języka Java.

Podstawy Programowania Podstawowa składnia języka C++

Prefiksy binarne. kibibit (Kibit) mebibit (Mibit) gibibit (Gibit) tebibit (Tibit) pebibit (Pibit) exbibit (Eibit) zebibit (Zibit) yobibit (Yibit)

2 Przygotował: mgr inż. Maciej Lasota

Wstęp do programowania

Informatyka 1. Wykład nr 4 ( ) Politechnika Białostocka. - Wydział Elektryczny. dr inŝ. Jarosław Forenc

Instrukcja do ćwiczeń nr 4 typy i rodzaje zmiennych w języku C dla AVR, oraz ich deklarowanie, oraz podstawowe operatory

BŁĘDY PRZETWARZANIA NUMERYCZNEGO

Podstawy Informatyki dla Nauczyciela

LABORATORIUM PROCESORY SYGNAŁOWE W AUTOMATYCE PRZEMYSŁOWEJ. Zasady arytmetyki stałoprzecinkowej oraz operacji arytmetycznych w formatach Q

Temat 1: Podstawowe pojęcia: program, kompilacja, kod

Wstęp do Programowania, laboratorium 02

Typy złożone. Struktury, pola bitowe i unie. Programowanie Proceduralne 1

Metody numeryczne I. Janusz Szwabiński. Metody numeryczne I (C) 2004 Janusz Szwabiński p.1/61

LibreOffice Calc VBA

Metoda znak-moduł (ZM)

Wyrażenia arytmetyczne

Program w C. wer. 12 z drobnymi modyfikacjami! Wojciech Myszka :59:

Operatory. Operatory bitowe i uzupełnienie informacji o pozostałych operatorach. Programowanie Proceduralne 1

Warto też w tym miejscu powiedzieć, że w C zero jest rozpoznawane jako fałsz, a wszystkie pozostałe wartości jako prawda.

Programowanie w C++ Wykład 2. Katarzyna Grzelak. 5 marca K.Grzelak (Wykład 1) Programowanie w C++ 1 / 41

Wstęp do informatyki- wykład 4 Deklaracja zmiennych Typy

Podstawy i języki programowania

Kodowanie liczb całkowitych w systemach komputerowych

Języki i metodyka programowania. Reprezentacja danych w systemach komputerowych

Transkrypt:

Pułapki liczb zmiennoprzecinkowych Adam Sawicki asawicki.info 24.09.2016

Agenda Liczby zmiennoprzecinkowe Budowa Typy możliwości i ograniczenia Typy w językach programowania Pułapki Zakres Precyzja Nieskooczone rozwinięcie Liczby całkowite Porównywanie Wartości specjalne Podsumowanie Ciekawostka: half-float 2

Liczby zmiennoprzecinkowe Liczby zmiennoprzecinkowe (floating point numbers) Przybliżona reprezentacja liczb rzeczywistych Mogą zawierad częśd całkowitą i ułamkową Mogą przyjmowad bardzo duże lub małe wartości Standard IEEE 754 Wspierane sprzętowo przez procesor Dostępne w różnych językach programowania 3

Liczby zmiennoprzecinkowe 1 10000010 01010000000000000000000 Znak Wykładnik Mantysa -1 1 2 3 1.3125 = -10.5 Przydatne narzędzie: IEEE 754 Converter 4

Typy możliwości i ograniczenia Floating-Point Formats Cheatsheet @ asawicki.info 5

Typy możliwości i ograniczenia Dwa najpopularniejsze: 32- i 64-bitowy Nazywane pojedynczej i podwójnej precyzji 6

Typy w językach programowania Język 32-bit Float 64-bit Float C, C++ * float double C# float double Java float double Delphi/Object Pascal Single Double SQL REAL FLOAT Python * float PHP * float JavaScript ** Number Lua ** number * Zazwyczaj zależnie od implementacji ** Jedyny dostępny typ liczbowy, nie ma typów całkowitych 7

Zakres Ograniczony zakres możliwych do zapisania wartości Wartośd najbliższa zero Wartośd największa/najmniejsza Jest szeroki, rzadko stanowi problem 8

Precyzja Precyzja określana jest liczbą cyfr znaczących Binarnych to liczba bitów mantysy + 1 Dziesiętnych podawana w przybliżeniu 9

Precyzja Precyzja jest względna Różnice między sąsiednimi możliwymi do zapisania wartościami są tym większe, im większa jest wartośd liczbowa. Wartości te rozmieszczone są gęściej w okolicy zera. float x = 1111.111111111111f; printf("%.16g\n", x); 10

Precyzja przykład #include <Windows.h> #include <stdio.h> int main() { float poczatek = (float)timegettime() / 1000.0f; DlugaOperacja(); float koniec = (float)timegettime() / 1000.0f; printf("dlugaoperacja trwala: %g s\n", koniec - poczatek); } timegettime zwraca czas od startu systemu, w milisekundach. Ile wynosi precyzja wyniku? Co jest źle w tym przykładzie? Jak to naprawid? 11

Precyzja przykład Jest to przykład tzw. catastrophic cancellation Zmienne poczatek i koniec mogą mied duże wartości. Niewielka różnica między nimi może byd niedokładna przez ograniczenia pracyzji. Czas od startu systemu Precyzja zmiennej 1 s 119 ns 10 000 s (3 godziny) 1 ms 100 000 s (1 dzieo) 7.81 ms 12

Precyzja przykład Rozwiązaniem jest zachowad czasy w ich natywnym typie, a dopiero ich różnicę zamienid na typ float. int main() { DWORD poczatek = timegettime(); DlugaOperacja(); DWORD koniec = timegettime(); float czastrwania = (float)(koniec - poczatek) / 1000.0f; printf("dlugaoperacja trwala: %g s\n", czastrwania); } Podobnie precyzyjny czas z funkcji QueryPerformanceCounter warto pozostawid jako 64- bitowy integer. 13

Nieskooczone rozwinięcie Liczba mająca skooczone rozwinięcie w zapisie dziesiętnym niekoniecznie ma takie w zapisie binarnym. Liczba System dziesiętny System binarny 1 + 1/2 1.5 1.1 π 3.1415927 11.001001 1/10 0.1 0.0001101 (!) 14

Liczby całkowite Wartości całkowite są w typach zmiennoprzecinkowych reprezentowane dokładnie Operacje na nich (dodawanie, odejmowanie, mnożenie) także dają dokładny wynik. Dzięki temu można ich używad zamiast liczb całkowitych (jak w JavaScript, Lua). float a = 256, b = 13; printf("%g\n", a * b); 15

Liczby całkowite jednak tylko do pewnej wartości maksymalnej! Powyżej tej wartości zaczynają przeskakiwad co 2, potem co 4 itd. Zakres dokładnych liczb całkowitych w X-bitowym float jest mniejszy, niż w X-bitowym integer. Zakres dokładnych liczb całkowitych w 64-bitowym float obejmuje cały zakres 32-bitowych integer. 16

Porównywanie Wyników obliczeo nie należy porównywad operatorem == ani!= Niedokładności na ostatnich miejscach po przecinku mogą spowodowad, że liczby nie będą identyczne. #include <stdio.h> int main() { float a = 1.0f / 10.0f; float b = 1.0f - 0.9f; printf("a=%g, b=%g\n", a, b); if (a == b) printf("zgadza sie.\n"); else printf("nie zgadza sie!\n"); } 17

Porównywanie #include <stdio.h> int main() { float a = 1.0f / 10.0f; float b = 1.0f - 0.9f; printf("a=%g, b=%g\n", a, b); if (a == b) printf("zgadza sie.\n"); else printf("nie zgadza sie!\n"); } a = 0x3dcccccd 0.100000001 b = 0x3dccccd0 0.100000024 18

Porównywanie Rozwiązaniem jest porównywanie z pewnym małym marginesem ±ε Ile powinien wynosid? To trudne pytanie. Zależy od rzędu wielkości wyniku i spodziewanych błedów. #include <stdio.h> #include <math.h> int main() { float a = 1.0f / 10.0f; float b = 1.0f - 0.9f; printf("a=%g, b=%g\n", a, b); if (fabsf(b - a) < 0.00001f) printf("zgadza sie.\n"); else printf("nie zgadza sie!\n"); } 19

Wartości specjalne Wartośd zmiennoprzecinkowa może byd jednego z kilku rodzajów, oprócz wartości normalnej (normal): Zero Są dwa zera, zależnie od bitu znaku: +0 i -0. Są sobie równe (+0 == -0), więc nie trzeba się nimi zajmowad. Wartośd zdenormalizowana (denormal, subnormal) Pozwala zapisad wartośd jeszcze mniejszą (bliższą zero), niż normalna. Po prostu działa nie trzeba się nią zajmowad. 20

Wartości specjalne INF nieskooczonośd (od Infinity) Również ma dwie wartości: +INF i -INF. Oznacza przepełnienie ponad maksymalną wartośd lub matematyczną nieskooczonośd. Drukowana jako 1.#INF lub inf. NaN nie liczba (od Not a Number) Wartośd niemożliwa do określenia, błąd obliczeo np. wynik niedozwolonej operacji. Drukowana jako 1.#IND (od indeterminate nieokreślony) lub nan itp. 21

Wartości specjalne test #include <stdio.h> #include <math.h> int main() { double zero = 0.0; double dwa = 2.0; printf(" 2 / 0 = %g\n", dwa / zero); printf("-2 / 0 = %g\n", -dwa / zero); printf(" 0 / 0 = %g\n", zero / zero); printf("log(0) = %g\n", log(zero)); printf("log(-2) = %g\n", log(-dwa)); printf("sqrt(-2) = %g\n", sqrt(-dwa)); double inf = dwa / zero; double nan = zero / zero; printf(" 2 + INF = %g\n", dwa + inf); printf(" 2 * INF = %g\n", dwa * inf); printf("-2 * INF = %g\n", -dwa * inf); printf(" 0 * INF = %g\n", zero * inf); printf(" 2 / INF = %g\n", dwa / inf); printf(" 0 / INF = %g\n", zero / inf); printf("inf + INF = %g\n", inf + inf); printf("inf - INF = %g\n", inf - inf); printf("inf * INF = %g\n", inf * inf); printf("inf / INF = %g\n", inf / inf); printf("2 + NaN = %g\n", dwa + nan); printf("2 * NaN = %g\n", dwa * nan); printf("2 / NaN = %g\n", dwa / nan); } printf(" INF > 2 = %s\n", inf > dwa? "true" : "false"); printf("-inf < 2 = %s\n", -inf < dwa? "true" : "false"); printf("2 == NaN = %s\n", dwa == nan? "true" : "false"); printf("nan == NaN = %s\n", -nan == nan? "true" : "false"); 22

Wartości specjalne test 23

Wartości specjalne INF i NaN zachowują się zgodnie z zasadami matematyki Każda operacja z NaN w wyniku daje NaN Każde porównanie z NaN daje false (nawet z samym sobą) Teoretycznie możnaby je wykorzystywad Wykrywad? Jawnie przypisywad? W praktyce oznaczają błąd obliczeo Niespodziewane zero, liczba ujemna, bardzo duża lub bardzo mała Należy im zapobiegad 24

Podsumowanie Liczby zmiennoprzecinkowe są przybliżeniem liczb rzeczywistych Mają złożoną budowę Mają ograniczony zakres i precyzję Warto byd świadomym ich cech i ograniczeo Nie każdą liczbę da się zapisad dokładnie Im większa wartośd, tym większy bezwzględny błąd Wyniki obliczeo mogą się różnid od spodziewanych na dalszych miejscach po przecinku Nie należy ich porównywad operatorem == ani!=, ale ±ε Wartości specjalne INF, NaN oznaczają błąd obliczeo 25

Ciekawostka: half-float Typ zmiennoprzecinkowy 16-bitowy precyzji połówkowej Bardzo ograniczone możliwości Zakres: maksimum to 65504 Precyzja: ok. 3 cyfr dziesiętnych Wciąż większy zakres i precyzja, niż bajt 0 255 Brak wsparcia sprzętowego w CPU Wsparcie sprzętowe w nowych GPU Wykorzystywany w grafice do zapisywania kolorów RGB 26

Pytania? 27