Преобразование из Variant String в Double игнорирует десятичную точку

У меня есть несколько простых строк кода:

var
  vRecordValue:Double;
begin
  vRecordValue:= someVariant;

Где someVariant - строка (тип 256).

В производственной системе у нас есть вариант «23,4», а vRecordValue становится 234. Я могу только воспроизвести, что мой системный разделитель - «,». В нашей производственной системе так и было, но мы изменили настройку и по-прежнему наблюдаем, как это происходит. Интересно отметить, что мы не можем воспроизвести это вообще, кроме как в режиме отладки (не знаю, какая здесь взаимосвязь) и путем выполнения простого теста.

Я исправил это явным преобразованием:

vRecordValue:= StrToFloatDef(VarToStrDef(someVariant, '0'), 0);

Вопросы:

  1. Есть ли другой способ игнорировать десятичную точку?
  2. Может ли кто-нибудь дать ссылку на то, как выполняется приведение по умолчанию из строки в двойное? Я хочу понять разницу.
  3. Есть ли способ кэширования разделителя, используемого в приведении по умолчанию, из значения при первом запуске кода? ... Сомнительно, но отчаянно пытается понять.

Спасибо,

Уэйн.


person wayju    schedule 31.03.2015    source источник
comment
Вы проверяли свои языковые настройки? В таких случаях я бы не стал полагаться на конкретный языковой стандарт, вместо этого использование фиксированного (английского) языкового стандарта для таких задач кажется уместным -   -  person JensG    schedule 31.03.2015
comment
Спасибо. Прости. Я должен был быть яснее. Когда я говорю, что разделитель - это запятая, это происходит из настроек локали. Наша производственная система находилась в Албании, поэтому я думаю, что мы столкнулись с этим.   -  person wayju    schedule 31.03.2015
comment
Чего вы на самом деле пытаетесь достичь?   -  person David Heffernan    schedule 31.03.2015
comment
@wayju: Я должен был сделать ставку. Я имел в виду именно этот случай.   -  person JensG    schedule 31.03.2015
comment
@Дэйвид. Спасибо. Я могу решить проблему, выполнив явное преобразование в соответствии со второй строкой кода. Насколько я понимаю и что все сказали, я смогу решить проблему, изменив настройки локали. К сожалению, изменение настроек на использование десятичного разделителя "." и разделитель тысяч "," не решает проблему. Я надеюсь, что кто-нибудь поможет мне понять.   -  person wayju    schedule 01.04.2015


Ответы (2)


Это ваши региональные настройки

Я сделал это демонстрационное приложение для тестирования:

procedure TForm60.FormCreate(Sender: TObject);
var
  vRecordValue: Double;
  sRecordValue: Variant;
begin
  sRecordValue:= '23.4';
  vRecordValue:= StrToFloatDef(VarToStrDef(sRecordValue, '0'), 0);
  ShowMessage(FloatToStr(vRecordValue));

  sRecordValue:= '23,4';
  vRecordValue:= StrToFloatDef(VarToStrDef(sRecordValue, '0'), 0);
  ShowMessage(FloatToStr(vRecordValue));
end;

В Дании (где я живу) мы используем десятичный разделитель, поэтому последний дает мне правильный результат

person Jens Borrisholt    schedule 31.03.2015
comment
Спасибо, Йенс. Я сделал аналогичный тест и обнаружил ту же проблему. Но я не понимаю, почему после изменения конфигурации нашей системы (замены запятой на точку) проблема не исчезла. Есть ли еще что-нибудь, что могло бы вызвать эту проблему? Или конфигурацию можно как-то кэшировать? Мы перезапустили сервер. - person wayju; 31.03.2015
comment
Я должен принять этот ответ с точки зрения причины возникновения проблемы. Это то, что я обнаружил в ходе тестирования, но не соответствует видимой конфигурации наших рабочих серверов. Мы выпустили патч с явным преобразованием, упомянутым в моем первоначальном вопросе, и, похоже, он работает на наших производственных серверах. Спасибо всем за помощь. - person wayju; 08.04.2015
comment
В моем сообщении ниже объясняется, почему изменение настроек не сработало ... потому что мы не меняли его для пользователя, запустившего службу! - person wayju; 06.08.2015

Что касается моего третьего вопроса. Проблема повторилась на этой неделе. Я не понимал, что локаль / региональные настройки устанавливаются только для текущего пользователя.

Чтобы скопировать настройки для пользователей системы, нам потребовалось использовать:

Панель управления> Регион и язык> Администрирование> Настройки копирования.

Вот почему при тестировании у меня были несоответствия. Это зависело от пользователя, от имени которого работало мое приложение, и от настроек пользователей.

person wayju    schedule 28.07.2015