Mam problem ze zrozumieniem zasad C dla jakiej precyzji zakładać przy drukowaniu podwajań lub przy zamianie ciągów na podwójne. Poniższy program powinien zilustrować mój punkt widzenia:Dziwne zachowanie podczas konwersji łańcuchów C do/z podwójnych
#include <errno.h>
#include <float.h>
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
int main(int argc, char **argv) {
double x, y;
const char *s = "1e-310";
/* Should print zero */
x = DBL_MIN/100.;
printf("DBL_MIN = %e, x = %e\n", DBL_MIN, x);
/* Trying to read in floating point number smaller than DBL_MIN gives an error */
y = strtod(s, NULL);
if(errno != 0)
printf(" Error converting '%s': %s\n", s, strerror(errno));
printf("y = %e\n", y);
return 0;
}
Wyjście mam kiedy skompilować i uruchomić ten program (na Core 2 Duo z gcc 4.5.2) jest:
DBL_MIN = 2.225074e-308, x = 2.225074e-310
Error converting '1e-310': Numerical result out of range
y = 1.000000e-310
Moje pytania są :
- Dlaczego x jest drukowany jako liczba niezerowa? Wiem, że kompilatory czasami promują podwojenia do wyższych typów precyzji do celów obliczeniowych, ale czy nie powinno się traktować x jako 64-bitowego podwójnego?
- Jeśli biblioteka C potajemnie używa liczb zmiennoprzecinkowych o rozszerzonej precyzji, dlaczego strtod ustawił wartość errno podczas próby konwersji tych małych liczb? I dlaczego tak czy inaczej daje prawidłowy wynik?
- Czy to zachowanie jest tylko błędem, wynikiem mojego szczególnego środowiska sprzętowego i programistycznego? (Niestety, nie mogę obecnie przetestować na innych platformach).
Dziękuję za pomoc, którą możesz udzielić. Postaram się wyjaśnić tę kwestię, gdy otrzymam informację zwrotną.
Dla jednego:' DBL_MIN = 2.225074e-308' nie ma sensu ponieważ minimalna wartość IEEE DP wynosi "4.94066e-324" .To wyjaśnia, dlaczego dzielenie przez '100' nadal działa poprawnie.Ale pytanie brzmi, dlaczego' DBL_MIN' nie jest '4.94066e-324' . – Mysticial
Wyjaśnienie poniżej: DBL_MIN jest najmniejszy _normalizowany_ wartość –