2010-06-09 16 views
6

Tengo un objeto COM con una función con un último argumento opcional. El IDL es un poco como esto:¿Por qué los valores por defecto de IDL se ven redondeados?

interface ICWhatever: IDispatch 
{ 
    [id(96)] HRESULT SomeFunction([in,defaultvalue(50.6)]float parameter); 
}; 

Esto funciona bien: si no se especifica el parámetro, 50.6 se rellena Sin embargo, en varios entornos de desarrollo (Excel VBA, Visual Basic 6) se redondea el valor predeterminado. antes de la exhibición. Después de escribir la llave abierta, veo:

algunaFuncion ([parámetro As Single = 51])

¿Alguien sabe qué es esto? ¿Es un error? Esto confunde el programador cliente ...

Respuesta

1

que era capaz de reproducir el problema que ha tenido (VBA), y que parece ser de hecho un error en el tratamiento del tipo Single por (específicamente) IDE VB. A saber, la VB IDE será indebidamente convertir el valor Single defecto para int antes de imprimirlo de nuevo (como parte de la firma del método) como un valor de punto flotante (truncado) de precisión simple.

Este problema no existe en el Editor de Microsoft Script, ni existe en OleView.exe etc.

Para probar, probar el siguiente valor predeterminado Single: 18446744073709551615.0. En mi caso, este valor está codificado correctamente en el TLB y debidamente representada por OleView.exe y por Microsoft Script Editor como 1.844674E+19. Sin embargo, se muestra como -2.147484E+09 en los IDE de VB. De hecho, la conversión de (float)18446744073709551615.0 a int produce -2147483648 que, mostrada como float, produce la salida VB IDE observada (incorrecta) -2.147484E+09.

De manera similar, 50.6 se lanza a int para producir 51, que luego se imprime como 51.

Para evitar este problema Double utilizar en lugar de Single, como Double se convierte y se visualizarse correctamente por todos los entornos de desarrollo que fue capaz de probar.


por la tangente, es probable que ya es consciente del hecho de que ciertos valores de punto flotante (como 0.1) no tienen una correspondiente exacta IEEE representación 754 y no se pueden distinguir de otros valores (por ejemplo, 0.1000000015.) por lo tanto, la especificación de un valor predeterminado de precisión doble valor de 0.1 se mostrará en la mayoría de los entornos de desarrollo como 0.100000001490116. Una manera de aliviar este problema precisión es elegir una escala diferente para sus parámetros (por ejemplo, cambio de segundos a milisegundos, por lo tanto 0.1 segundos se convertirían en 100 milisegundos, sin ambigüedades representable como tanto de punto flotante de precisión simple y doble, así como los valores integrales/parámetros.)

Cuestiones relacionadas