Wersja beta#
TO JEST WERSJA TESTOWA
Ten kalkulator dopiero powstaje - właśnie nad nim pracujemy.
To znaczy, że może działać poprawnie, ale nie musi.
Jak najbardziej możesz go użyć. Może nawet uzyskasz poprawne wyniki.
Prosimy jednak, abyś sprawdził uzyskane wyniki we własnym zakresie. Potwierdź je przed wykorzystaniem, bo mogą być błędne.
W każdym razie - prace trwają. Ta podstrona powinna zostać ukończona już wkrótce. Zapraszamy !
Jeśli masz jakieś pomysły, uwagi - daj znać !
Ten kalkulator dopiero powstaje - właśnie nad nim pracujemy.
To znaczy, że może działać poprawnie, ale nie musi.
Jak najbardziej możesz go użyć. Może nawet uzyskasz poprawne wyniki.
Prosimy jednak, abyś sprawdził uzyskane wyniki we własnym zakresie. Potwierdź je przed wykorzystaniem, bo mogą być błędne.
W każdym razie - prace trwają. Ta podstrona powinna zostać ukończona już wkrótce. Zapraszamy !
Jeśli masz jakieś pomysły, uwagi - daj znać !
Dane do obliczeń#
Typ danych | ||
Zapis w systemie dziesiętnym (decymalnym) | ||
Zapis w systemie szesnastkowym (heksadecymalnym) | ||
Zapis w systemie binarnym (dwójkowym) |
Reprezentacja binarna#
Znak (1 bit) | Wykładnik (11 bit) | Mantysa (52 bit) | |
---|---|---|---|
Bin | |||
Hex | |||
Dec |
Trochę informacji#
- Liczby zmiennoprzecinkowe to typ danych służący do reprezentacji liczb rzeczywistych w pamięci komputera.
- Ze względu na ograniczoną pamięć komputera, liczby zmiennoprzecinkowe są jedynie przybliżeniem liczb rzeczywistych.
- Istnieje wiele różnych standardów zapisu liczb zmiennoprzecinkowych, jednak większość współczesnych architektur implementuje standard IEEE 754.
- Liczba zmiennoprzecinkowa w systemie IEEE 754 przechowuje liczbę w postaci:
gdzie:
- z = część określająca znak liczby,
- m = część określająca mantysę liczby zapisaną w systemie dwójkowym,
- w = cześć określająca wykładnik (pozycję przecinka).
- z = część określająca znak liczby,
- W porównaniu do liczb stałoprzecinkowych, liczby zmiennoprzecinkowe pozwalają zapisać liczby z większego zakresu kosztem obniżonej precyzji.
- Standard IEEE 754 definiuje następujące typy danych:
- liczba pojedynczej precyzji (32-bit) (ang. single precision):
- znak - 1 bit,
- wykładnik - 8 bitów,
- mantysa - 23 bity,
- znak - 1 bit,
- liczba podwójnej precyzji (64-bit) (ang. double precision):
- znak - 1 bit,
- wykładnik - 11 bitów,
- mantysa - 52 bity.
- znak - 1 bit,
- liczba o rozszerzonej precyzji (80-bit) (ang. extended precision):
- znak - 1 bit,
- wykładnik - 15 bitów,
- mantysa - 64 bity.
- znak - 1 bit,
- liczba pojedynczej precyzji (32-bit) (ang. single precision):
- Standard IEEE 754 definiuje następujące sposoby zaokrąglania liczb:
- Zaokrąglanie do najbliższej wartości (ang. round to nearest),
- zaokrąglanie w kierunku zera (ang. round toward 0),
- zaokrąglanie w stronę dodatniej nieskończoności (ang. round toward +infinity),
- zaokrąglanie w stronę ujemnej nieskończoności (ang. round toward -infinity).
- Zaokrąglanie do najbliższej wartości (ang. round to nearest),
- Domyślnym sposobem zaokrąglania w systemie IEEE 754 jest zaokrąglanie do najbliższej wartości.
Koprocesor x87 a jednostka SIMD#
- Na procesorach z rodziny x86 (IA-32, 32-bit), liczby zmiennoprzecinkowe są najczęściej realizowane przez koprocesor x87. W przypadku kodu 64-bitowego (architektura x64) coraz częściej wykorzystywana jest jednostka SIMD (instrukcje SSEx).
- Koprocesor x87 wewnętrznie stosuje liczby 80-bitowe, podczas gdy precyzja jednostki SIMD ograniczona jest do 64 bitów. Fakt ten może powodować nieco inne wyniki w zależności czy korzystamy z architektury x64 (64-bity) czy x86 (32-bity).
- Aby pokazać różnice jakie mogą pojawić się pomiędzy architekturą x86 (koprocesor x87), a x64 (jednostka SIMD) można użyć poniższego programu w języku C:
#include <stdio.h>
#include <stdint.h>
void printFloat(float x)
{
uint32_t hex = *(uint32_t *) &x;
printf("%.8f = 0x%08x\n", x, hex);
}
void printFloatRational(int x, int y)
{
float res = (float) x / y;
uint64_t hex = *(uint32_t *) &res;
printf("%d / %d = %.8f = 0x%08x\n", x, y, res, hex);
}
int main()
{
printFloatRational(1, 3);
printFloatRational(10, 30);
printFloatRational(100, 300);
printFloatRational(1000, 3000);
printFloatRational(12345678, 87654321);
printFloatRational(87654321, 12345678);
printFloatRational(12345678, 87654321);
printFloatRational(12354124, 54123903);
printFloat(0.33333333f);
printFloat(0.5f);
printFloat(0.12345678f);
printFloat(0.87654321f);
printFloat(12345678.12345678f);
}
Powyższy program, skompilowany przez gcc w wersji 7.2.0 w wersji 64-bitowej, daje następujący wydruk:1 / 3 = 0.33333334 = 0x3eaaaaab
10 / 30 = 0.33333334 = 0x3eaaaaab
100 / 300 = 0.33333334 = 0x3eaaaaab
1000 / 3000 = 0.33333334 = 0x3eaaaaab
12345678 / 87654321 = 0.14084506 = 0x3e1039b0
87654321 / 12345678 = 7.10000038 = 0x40e33334
12345678 / 87654321 = 0.14084506 = 0x3e1039b0
12354124 / 54123903 = 0.22825633 = 0x3e69bc07
0.33333334 = 0x3eaaaaab
0.50000000 = 0x3f000000
0.12345678 = 0x3dfcd6e9
0.87654322 = 0x3f606523
12345678.00000000 = 0x4b3c614e
podczas gdy ten sam program skompilowany przez gcc 4.9.3 w wersji 32-bitowej, zwraca:1 / 3 = 0.33333334 = 0x3eaaaaab
10 / 30 = 0.33333334 = 0x3eaaaaab
100 / 300 = 0.33333334 = 0x3eaaaaab
1000 / 3000 = 0.33333334 = 0x3eaaaaab
12345678 / 87654321 = 0.14084506 = 0x3e1039b0
87654321 / 12345678 = 7.10000038 = 0x40e33334
12345678 / 87654321 = 0.14084506 = 0x3e1039b0
12354124 / 54123903 = 0.22825634 = 0x3e69bc08
0.33333334 = 0x3eaaaaab
0.50000000 = 0x3f000000
0.12345678 = 0x3dfcd6e9
0.87654322 = 0x3f606523
12345678.00000000 = 0x4b3c614e - Niewielka różnica zaobserwowana podczas obliczania wyniku dzielenia:12354124 / 54123903związana jest z faktem, że wygenerowany przez gcc kod 32-bitowy korzysta z instrukcji koprocesora x87 (który operuje wewnętrznie na liczbach 80-bitowych):
fild DWORD PTR [ebp+8] ; załaduj liczbę 12354124 na stos x87 (80 bit)
fild DWORD PTR [ebp+12] ; załaduj liczbę 54123903 na stos x87 (80 bit)
fdivp st(1), st ; oblicz wynik dzielenia 12354124 / 54123903
podczas gdy ten sam kod, na architekturze 64-bitowej korzysta z jednostki SIMD:cvtsi2ss xmm0, DWORD PTR 16[rbp] ; załaduj liczbę 12354124 do rejestru xmm0
cvtsi2ss xmm1, DWORD PTR 24[rbp] ; załaduj liczbę 54123903 do rejestru xmm1
divss xmm0, xmm1 ; oblicz wynik dzielenia 12354124 / 54123903
Tagi i linki do tej strony#
Tagi:
liczby_zmiennoprzecinkowe · double_reprezentacja_binarna · double_reprezentacja_bitowa · float_reprezentacja_binarna · float_reprezentacja_bitowa · format_single_precision · format_double_precision · ieee754
Tagi do wersji anglojęzycznej:
Jakie tagi ma ten kalkulator#
Permalink#
Poniżej znaduje się permalink. Permalink to link, który zawiera dane podane przez Ciebie. Po prostu skopiuj go do schowka i podziel się swoją pracą z przyjaciółmi: