Aparte de posiblemente de diferentes tamaños registros, has desnormalizado de punto flotante (CQ ras-a-cero) que preocuparse (ver Why does changing 0.1f to 0 slow down performance by 10x?)
Sólo para dar una idea de lo extraño que esto podría conducir a, intenta este bit de código:
float a = 0.000000000000000000000000000000000000000047683384;
const float b = 0.000000000000000000000000000000000000000047683384;
float aa = a, bb = b;
#define SUPPORT_DENORMALIZATION ({volatile double t=DBL_MIN/2.0;t!=0.0;})
printf("support denormals: %d\n",SUPPORT_DENORMALIZATION);
printf("a = %.48f, aa = %.48f\na==aa %d, a==0.0f %d, aa==0.0f %d\n",a,aa,a==aa,a==0.0f,aa==0.0f);
printf("b = %.48f, bb = %.48f\nb==bb %d, b==0.0f %d, bb==0.0f %d\n",b,bb,b==bb,b==0.0f,bb==0.0f);
que da o bien: (compilado sin rubor a cero)
support denormals: 1
a = 0.000000000000000000000000000000000000000047683384, aa = 0.000000000000000000000000000000000000000047683384
a==aa 1, a==0.0f 0, aa==0.0f 0
b = 0.000000000000000000000000000000000000000047683384, bb = 0.000000000000000000000000000000000000000047683384
b==bb 1, b==0.0f 0, bb==0.0f 0
o: (compilado con gcc -ffast-math
)
support denormals: 0
a = 0.000000000000000000000000000000000000000000000000, aa = 0.000000000000000000000000000000000000000000000000
a==aa 1, a==0.0f 1, aa==0.0f 1
b = 0.000000000000000000000000000000000000000047683384, bb = 0.000000000000000000000000000000000000000000000000
b==bb 1, b==0.0f 0, bb==0.0f 1
Cuando la última línea es, por supuesto, el impar hacia fuera: b==bb && b!=0.0f && bb==0.0f
sería cierto.
Así que si todavía estás pensando en comparar los valores de punto flotante, al menos mantente alejado de los valores pequeños.
actualización para compensar algunos comentarios acerca de este ser debido al uso de flotadores en lugar de dobles, que también trabaja para el doble, pero se necesitaría establecer la constante a algún lugar por debajo DBL_MIN
, por ejemplo, 1e-309
.
actualización 2 un ejemplo de código relacionado con algunos comentarios realizados a continuación. Esto demuestra que el problema existe en dobles, así, y que las comparaciones puede llegar a ser inconsistentes (cuando ras a cero está habilitado)
double a;
const double b = 0.00000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000001225;
const double c = 0.00000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000002225;
printf("b==c %d\n",b==c);
a = b;
printf("assigned a=b: a==b %d\n",a==b);
a = c;
printf("assigned a=c: a==b %d\n",a==b);
de salida:
b==c 0
assigned a=b: a==b 1
assigned a=c: a==b 1
La cuestión muestra en la última línea, donde ingenuamente esperaría que a==b
se convirtiera en falso después de asignar a=c
con c!=b
.
¿Se cambiará el valor de '_val' durante el tiempo de ejecución? –
Sí, se puede cambiar a un valor real (pero definitivamente '> -1'). No estoy seguro si habrá una necesidad de 'reiniciarlo' de nuevo al especial. –
Prefiero esperar que copiar un valor de punto flotante no lo altere en absoluto, y que dadas dos variables 'a' y' b' del mismo tipo primitivo, asignando 'a = b' resulta en' a == b' siendo cierto Sin embargo, estoy basando esta suposición en el sentido común, que se sabe que me decepcionó en el pasado. – Rook