Почему значения по умолчанию IDL выглядят округленными?
У меня есть COM-объект с функцией с необязательным последним аргументом. IDL немного похож на это:
interface ICWhatever: IDispatch
{
[id(96)] HRESULT SomeFunction([in,defaultvalue(50.6)]float parameter);
};
Это работает нормально: если я не укажу параметр, заполняется 50.6. Но в нескольких средах разработки (Excel VBA, VB6) значение по умолчанию округляется перед отображением. После ввода открытой скобки я вижу:
SomeFunction ([параметр As Single = 51])
Кто-нибудь знает почему это? Это ошибка? Это запутает клиентских программистов...
1 ответ
Я смог воспроизвести проблему, с которой вы столкнулись (VBA), и это действительно ошибка в лечении Single
введите (в частности) VB IDE. А именно, VB IDE будут неправильно разыгрывать Single
значение по умолчанию int
перед его повторной печатью (как часть сигнатуры метода) в виде (усеченного) значения с плавающей точкой одинарной точности.
Эта проблема не существует в редакторе сценариев Microsoft и не существует в OleView.exe
и т.п.
Чтобы проверить, попробуйте следующее Single
значение по умолчанию: 18446744073709551615.0
, В моем случае это значение правильно закодировано в TLB и правильно отображается OleView.exe
и Microsoft Script Editor, как 1.844674E+19
, Тем не менее, он отображается как -2.147484E+09
в VB IDE. Действительно, кастинг (float)18446744073709551615.0
в int
производит -2147483648
который отображается как float
, выдает наблюдаемый (неправильный) вывод VB IDE -2.147484E+09
,
Так же, 50.6
попадает в int
производить 51
, который затем распечатывается как 51
,
Чтобы обойти эту проблему, используйте Double
вместо Single
, как Double
конвертируется и отображается правильно всеми IDE, которые я смог протестировать.
По касательной вы, вероятно, уже знаете о том, что некоторые значения с плавающей запятой (например, 0.1
) не имеют соответствующего точного представления IEEE 754 и не могут быть отличены от других значений (например, 0.1000000015
.) Таким образом, указав значение двойной точности по умолчанию 0.1
будет отображаться в большинстве IDE как 0.100000001490116
, Одним из способов решения этой проблемы точности является выбор другого масштаба для ваших параметров (например, переключение с секунд на миллисекунды, таким образом, 0.1
секунды станут 100
миллисекунды, однозначно представляемые как с плавающей запятой одинарной и двойной точности, а также как целые значения / параметры.)