File: Stare vježbe/vjezbe02/14__limits_float.c

  1. /*
  2.   14__limits_float.c
  3.   Greske zaokruzivanja kod tipa float
  4.   Napomena: Ovaj primjer obavezno compilirati s ANSI C
  5.   kompatibilnim compilerom (npr. GCC)
  6. */
  7.  
  8. #include <stdio.h>
  9.  
  10. /* Tip float <--> IEEE-754 standard za jednostruku preciznost:
  11.   |x|xxxxxxxx|xxxxxxxxxxxxxxxxxxxxxxx| (32 bita)
  12.   predznak - 1 bit
  13.   karakteristika - 8 bitova (sluzi za spremanje eksponenta)
  14.   mantisa - 23 bita
  15. */
  16.  
  17. int main ()
  18. {
  19. float f;
  20. double d;
  21.  
  22. /* 1E9 i 1E10 ce se ispisati ispravno (tocno),
  23.   no vec 1E11 (pa i 1E12) vise nece */
  24. f=1E9f;
  25. printf("1E9: %f\n", f);
  26. f=1E10f;
  27. printf("1E10: %f\n", f);
  28. f=1E11f;
  29. printf("1E11: %f\n", f);
  30. f=1E12f;
  31. printf("1E12: %f\n\n", f);
  32.  
  33. /* Uzrok pogresnog ispisivanja gornjih brojeva lezi u cinjenici da
  34.   tip float ima preciznost od 23 binarne znamenke.
  35.   Slijedeci primjer pokazat ce nam koja je to granica kada tip float
  36.   postaje "neprecizan".
  37.   */
  38. /* Primijetimo da je 16777215 == 2^24-1 */
  39. f=16777215.f;
  40. printf("2^24-1: %f\n", f);
  41. f=f+1;
  42. printf("2^24: %f\n", f);
  43. /* Da bismo mogli zbrojiti 2^24 i 1 trebale bi nam minimalno 24
  44.   binarne znamenke u mantisi.
  45.   Stoga ispada da 2^24+1 iznosi 2^24. */
  46. f=f+1;
  47. printf("2^24+1: %f\n\n", f);
  48.  
  49. /* Ukoliko prethodni primjer provedemo na tipu double vidjet cemo da
  50.   se nece pojaviti navedeni problem buduci da tip double (64 bita)
  51.   ima (daleko) vecu preciznost od tipa float */
  52. d=16777215.;
  53. printf("2^24-1: %f\n", d);
  54. d=d+1;
  55. printf("2^24: %f\n", d);
  56. d=d+1;
  57. printf("2^24+1: %f\n", d);
  58.  
  59. return 0;
  60. }
  61.