Почему значения по умолчанию IDL выглядят округленными? - PullRequest
6 голосов
/ 09 июня 2010

У меня есть 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 Ответ

1 голос
/ 09 сентября 2010

Мне удалось воспроизвести проблему, с которой вы столкнулись (VBA), и, похоже, это действительно ошибка при обработке типа Single с помощью (в частности) VB IDE .А именно, в VB IDE будет неправильно приведено значение Single по умолчанию к int перед его повторной печатью (как часть сигнатуры метода) в виде (усеченного) значения с плавающей запятой одинарной точности.

Эта проблема не существует в Microsoft Script Editor и не существует в 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 миллисекундами, что однозначно представляется как с плавающей запятой одинарной, так и двойной точности, а такжекак интегральные значения / параметры.)

...