Top.Mail.Ru
Мастера DELPHI, Delphi programming community Титульная страница Поиск, карта сайта Написать письмо 
| Новости | Поиск | FAQ | Статьи | Книги | Новости VCL |
| Форумы ЧАТ | Орешник | KOL и MCK |
Форумы -» Основная («Начинающим»)/ Базы / WinAPI / Компоненты / Сети / Media / Игры / Corba и COM / KOL / FreePascal / .Net / Прочее / RSDN.ORG

« предыдущая ветвь | форум | следующая ветвь »

Почему StrToFloat обрезает строку?


alsov ©   (2007-11-09 13:24:00) 

Приветствую, Мастера

Столкнулся с проблемой.
В строке число '1.2345678901234567890123456789E+49'.
После перобразования получаю 1.23456789012346E49
Почему обрезает?

Делаю так
ShowMessage(FloatToStr(StrToFloat('1.2345678901234567890123456789E+49')));


Leonid Troyanovsky   (2007-11-09 19:13:00) [1]


> alsov ©   (09.11.07 17:59) [12]

> вот такая функция получилась

See SysUtils.TryStrToFloat

--
Regards, LVT.


alsov   (2007-11-09 17:59:00) [2]


> Leonid Troyanovsky ©  


Само собой

вот такая функция получилась


function IsFloat(AValue: string): Boolean;
const
 MAX_MANTISA = 999999999999999;
 MAX_EXP = 999;
var
 p: Integer;
 i: Int64;
 s: string;
begin
 result := False;
 AValue := Trim(AValue);

 if AValue='' then Exit;
 AValue := UpperCase(AValue);

 //Есть ли експонента
 p := Pos('E', AValue);
 //число в экспоненциальном виде
 if p>0 then
 begin
   //проверить експоненту
   s := Trim(Copy(AValue, p+1, 5));
   if s>'' then
   begin
     if not TryStrToInt64(s, i) then exit;
     if Abs(i)>MAX_EXP then Exit;
   end;

   //преобразовать для проверки мантиссы
   AValue := Copy(AValue, 1, p-1);
 end;
 //первобразвать в целое
 AValue := StringReplace(AValue, DecimalSeparator, '', []);
 if not TryStrToInt64(AValue, i) then exit;
 //сравнить с максимально возможным
 if Abs(i)>MAX_MANTISA then Exit;

 result := True;
end;


Leonid Troyanovsky   (2007-11-09 16:38:00) [3]


> alsov ©   (09.11.07 16:21) [10]

> в експоненте 3 числа

У оной и знак бывает.

--
Regards, LVT.


alsov   (2007-11-09 16:21:00) [4]


> Самое простое - установить MaxLength в разумную величину.


Вобщем решил так

Проверять число по маске
-999999999999999E999
где 9 - любое число от 0 до 9,
в мантисе не больше 15 чисел (разделитель ожет присутстовать)
в експоненте 3 числа


Германн   (2007-11-09 16:10:00) [5]


> Какие правила лучше наложить на edit?

Самое простое - установить MaxLength в разумную величину.


alsov   (2007-11-09 16:07:00) [6]

Тогда еще встречный вопрос

Какие правила лучше наложить на edit?


Германн   (2007-11-09 16:07:00) [7]


> И чтобы избежать таких чисел, в интерфейсе запрещать вводить
> бгольшие числа в десятичном формате, а зставлять вводить
> в экспоненциальном.
>

Дело не столько в "формате", сколько в "точности" ака количестве значащих цифр.


alsov   (2007-11-09 15:58:00) [8]

Спасибо за статью - узнал много нового

Теперь подитожу (если конечно правильно понял)
Так как мантиса в числе равна 8 байт, то при переводе текста в число она соответсвенно округляется.

И чтобы избежать таких чисел, в интерфейсе запрещать вводить бгольшие числа в десятичном формате, а зставлять вводить в экспоненциальном.


Германн   (2007-11-09 13:35:00) [9]


> Почему StrToFloat обрезает строку?
>
> alsov ©   (09.11.07 13:24)
>
>

http://www.delphikingdom.com/asp/viewitem.asp?catalogid=374


Правильный_Вася   (2007-11-09 13:32:00) [10]

почитай про значащие цифры
для длинной арифметики нужны другие типы данных


alsov   (2007-11-09 13:30:00) [11]

Такое тоже рубит
var
val: Extended;
begin
 val := StrToFloat('12345678901234567890123456789123456789012345678901234567891234567890 12345678901234567891234567890123456789012345678912345678901234567890123456789');
 ShowMessage(FloatToStr(val));
end;


alsov   (2007-11-09 13:28:00) [12]

Почему дабл
написано что
function StrToFloat(const S: string): Extended;


Reindeer Moss Eater   (2007-11-09 13:25:00) [13]

Потому что есть дабл и потому что есть значащие цифры


Наверх

Титульная страница Поиск, карта сайта Написать письмо