Dziwne zachowanie funkcji pow()

Dziwne zachowanie funkcji pow()
S7
  • Rejestracja: dni
  • Ostatnio: dni
  • Postów: 363
0
Kopiuj
unsigned long long potega = pow(112890625, 2);                  
unsigned long long inna_potega = 112890625 * 112890625; 

potega = 12744293212890624
inna_potega = 12744293212890625
dlaczego funkcja pow() zwraca błędny wynik ?

kq
  • Rejestracja: dni
  • Ostatnio: dni
  • Lokalizacja: Szczecin
4

Bo liczby zmiennoprzecinkowe mają ograniczoną precyzję.
http://kaczus.ppa.pl/art/liczbyzmiennoprzecinkowe,19.html

swoją drogą, dziwne że wartością drugiej zmiennej nie jest -35772927 (w końcu masz tam UB)

S7
  • Rejestracja: dni
  • Ostatnio: dni
  • Postów: 363
0

Przepraszam że napisałem ll, chodziło mi o unsigned long long

kq
  • Rejestracja: dni
  • Ostatnio: dni
  • Lokalizacja: Szczecin
0

Moja odpowiedź jest nadal poprawna (pow przyjmuje i zwraca double), ale dziwne że skracasz unsigned long long do ll, bardzo to mylące.

MarekR22
  • Rejestracja: dni
  • Ostatnio: dni
1
kq napisał(a):

Bo liczby zmiennoprzecinkowe mają ograniczoną precyzję.

http://kaczus.ppa.pl/art/liczbyzmiennoprzecinkowe,19.html

swoją drogą, dziwne że wartością drugiej zmiennej nie jest -35772927 (w końcu masz tam UB)

Wynik mieści w 54 bitach, więc zmieści się long long int (nawet ze znakiem), z tego co mi wiadomo w takim wyrażeniu kompilator potrafi rozkminić i użyć właściwego typu dla literałów zamiast zwykłego int.
A różnica wyników jest rezultatem dwóch czynników.

  • Jak działa pow pod spodem (exp(log(a)*b))
  • oraz tego, że mantysa double (typ zwracany przez pow) ma mniej bitów niż 54 bity (53), więc musi nastąpić zaokrąglenie.

https://godbolt.org/z/Pfjr3K

Zarejestruj się i dołącz do największej społeczności programistów w Polsce.

Otrzymaj wsparcie, dziel się wiedzą i rozwijaj swoje umiejętności z najlepszymi.