Странности типа double

 

Народ подскажите как бороться с количеством знаков дробной части!!! Я уже все мозги вывихнул!

Имеем строку содержащую число с плавающей точкой, нужно его поместить в переменную типа double для дальнейшего использования, причем без каких либо округлений дробной части. Естественной реакцией на задачу было использование функции StrToDouble, но эта зараза округляет число до 4 знаков после запятой!!! Возникает естественный вопрос:

- "А кто ее просил об этом???"

Пошел по пути создания своей функции Str2Double, ниже ее привожу:

double Str2Double(string a_data)
{
  string sdata;
  int data1;
  int data2;
  int i_pos;
  int iMnoj;
  double d;
 
  i_pos = StringFind(a_data,".",0);
  if(i_pos > -1){
    sdata = StringSubstr(a_data,i_pos+1,StringLen(a_data)-i_pos);
    data1 = StrToInteger(StringSubstr(a_data,0,i_pos));
    data2 = StrToInteger(sdata);
    iMnoj = MathPow(10,StringLen(sdata));
    return(data1+(MathMod(data2,iMnoj) / iMnoj));
  } else {
    return(StrToDouble(a_data));
  }
}


До строки возврата, а конкретнее

return(data1+(MathMod(data2,iMnoj) / iMnoj));

все идет нормально, но

data1+(MathMod(data2,iMnoj) / iMnoj)

снова округляет дробную часть до 4 знаков!!! Что за дебилизм? Как это побороть? В частности у меня в поступающих данных есть много чисел с 5 знаками после запятой, а MQL мне режет до четырех хоть тресни.

 

is_vale:

было использование функции StrToDouble, но эта зараза округляет число до 4 знаков после запятой!!!

а как проверили ?
 
is_vale:

Народ подскажите как бороться с количеством знаков дробной части!!! Я уже все мозги вывихнул!

Имеем строку содержащую число с плавающей точкой, нужно его поместить в переменную типа double для дальнейшего использования, причем без каких либо округлений дробной части. Естественной реакцией на задачу было использование функции StrToDouble, но эта зараза округляет число до 4 знаков после запятой!!! Возникает естественный вопрос:

- "А кто ее просил об этом???"

Пошел по пути создания своей функции Str2Double, ниже ее привожу:


До строки возврата, а конкретнее

все идет нормально, но

снова округляет дробную часть до 4 знаков!!! Что за дебилизм? Как это побороть? В частности у меня в поступающих данных есть много чисел с 5 знаками после запятой, а MQL мне режет до четырех хоть тресни.


string value=DoubleToStr(1.28473418, 5);
  // содержимое строки value - "1.28473"
 
sergeev:
а как проверили ?


допотопным Print. До указанного места все идет как по нотам, а далее MQL хватает шашку и...
 
khorosh:
string value=DoubleToStr(1.28473418, 5);

Сорри, разговор про "StrToDouble"
 
is_vale:

допотопным Print. До указанного места все идет как по нотам, а далее MQL хватает шашку и...

Почитайте на него документацию:

void Print( ...)
Печатает некоторое сообщение в журнал экспертов. Параметры могут иметь любой тип. Количество параметров не может превышать 64.

Массивы нельзя передать в функцию Print(). Массивы должны быть напечатаны поэлементно.

Данные типа double выводятся с 4 десятичными цифрами после точки. Чтобы получить большую точность, следует использовать функцию DoubleToStr().
 
ilunga:

Почитайте на него документацию:

void Print( ...)
Печатает некоторое сообщение в журнал экспертов. Параметры могут иметь любой тип. Количество параметров не может превышать 64.

Массивы нельзя передать в функцию Print(). Массивы должны быть напечатаны поэлементно.

Данные типа double выводятся с 4 десятичными цифрами после точки. Чтобы получить большую точность, следует использовать функцию DoubleToStr().

Да ради бога! Причем тут это? Объясню иначе:

Индикатор получает уровень (число - цена) в строковом виде, создает объект "трендовая линия" которой, в качестве цены, передает данное значение преобразовав его в число с плавающей точкой. Результат - на входе имеем 5 знаков после запятой (имеется в виду входная строка), а после преобразования StrToDouble число округленное до ЧЕТЫРЕХ знаков после запятой. Собственно это значение созданная трендовая линия и получает! А нужно буз всяких округлений подать то число которое пришло.

Тот же эффект наблюдается и в вышеописанной функции, а конкретнее при вычислении:

data1+(MathMod(data2,iMnoj) / iMnoj)

Документацию читать я умею, и как вывести число через Print тоже знаю, а вопрос касался совершенно иного...

 
is_vale:

Да ради бога! Причем тут это? Объясню иначе:

Индикатор получает уровень (число - цена) в строковом виде, создает объект "трендовая линия" которой, в качестве цены, передает данное значение преобразовав его в число с плавающей точкой. Результат - на входе имеем 5 знаков после запятой (имеется в виду входная строка), а после преобразования StrToDouble число округленное до ЧЕТЫРЕХ знаков после запятой. Собственно это значение созданная трендовая линия и получает! А нужно буз всяких округлений подать то число которое пришло.

Тот же эффект наблюдается и в вышеописанной функции, а конкретнее при вычислении:

Документацию читать я умею, и как вывести число через Print тоже знаю, а вопрос касался совершенно иного...

покажите участок кода где Вы используете StrToDouble
 
is_vale:
допотопным Print.
Проверьте еще раз.
 
ilunga:
покажите участок кода где Вы используете StrToDouble
Содержимое файла:

Label_name;1.33147

int first_bar=WindowFirstVisibleBar();
int lengs=20;
double price;
string other;
string s;

handle=FileOpen(StringConcatenate("\\file.txt",FILE_READ|FILE_CSV);
other = FileReadString(handle);
s = FileReadString(handle); // Тут получаем 1.33147
price = StrToDouble(s);     // А тут уже 1.3315 что можно увидеть в свойствах созданнго объекта!
ObjectCreate("NAME",OBJ_TREND,0,Time[first_bar],price,Time[first_bar-lengs],price);
 
is_vale:
Содержимое файла:

Label_name;1.33147


убрал

StringConcatenate(

чтобы скомпилировалось.

Запустил. создалась линия на уровне 1.33147

Что я делаю не так? ((

Причина обращения: