Trik z liczbą zmiennoprzecinkową.

0

Witam

Jeżeli zapiszemy do zmiennej float liczbę o nieskończonym rozwinięciu dziesiętnym to cała ta liczba się nie zmieści, zostanie jakby ucięta.
Czy możliwe że zmienna float będzie miała mniej bitów np (80) niż rejestr w FPU dzięki czemu taki kawałek kodu się wykona?

#include <iostream>

int main(void)
{
	float  a = 1/3; /// 0,(3) zapisane np do 6 miejsca po przecinku
	
	if(a !=  (1/3) /* 0,(3) zapisane do 8 miejsca po przecinku*/ )
	{
		std::cout << "nie identyczne";
	}
	
	return 0;
}
3

Kilka uwag:

  1. "Jeżeli zapiszemy do zmiennej float liczbę o nieskończonym rozwinięciu dziesiętnym..." - raczej o nieskończynym rozwinięciu binarnym
  2. 1/3 to integer, czyli 0.
  3. 1/3. to double
  4. 1/3.f to float
    czyli
    float a = 1/3.f;
 
    if (a != 1/3.f) {
        cout << "no";
    }
2

Dodatkowo w podanym przez Ciebie przypadku większość współczesnych kompilatorów wyoptymalizuje obie stałe i zauważy, że warunek nie jest nigdy spełniony (bo porównujemy ze stałą) więc zapewne wytnie cały kod i zostanie pusta funkcja main.

https://godbolt.org/g/o3E7wd

0

Tutaj masz prawdziwy trik z liczbą zmiennoprzecinkową:

#include <math.h>
#include <stdio.h>
#include <stdlib.h>

int
main()
{
	float a = NAN;

	if (a != a) {
		printf("buggy!?\n");
	}
	return (0);
}
0

Tylko wskażę, że przy wielokrotnych obliczeniach 1./3 staci swoją precyzję. Ja zawsze zapisuję (a< 1.0/3-EPSILON || a>1.0/3+EPSILON) zamiast (a!=1./3). Inaczej jednej trzeciej możemy się nigdy nie doczekać.

#define EPSILON 0.0000001 /* lub więcej lub mniej zależnie od precyzji */

1 użytkowników online, w tym zalogowanych: 0, gości: 1