Самый простой способ посчитать количество знаков после запятой? - страница 2

 
Через логарифм вот так
MathAbs( MathLog10(a))

но только если в конце числа стоит единица
 
Alexey Volchanskiy:

Ну студент, пишет контрольную, во пристали к человеку )) На бирже studwork таких задач полно, а тут сам старается, молодец!

нет, дедушка Волчанский, не угадал.)

 
igrok333:
Через логарифм вот так

но только если в конце числа стоит единица

0.02 поделите на натуральный логарифм из 10 и выделите целую часть

 
Iurii Tokman:

0.02 поделите на натуральный логарифм из 10 и выделите целую часть

это шутка?

MathLog(10)=2.30

0.02/2.30= 0.00868589

Тут нет целой части.
 
igrok333:
Есть переменная.
Например:
double а=0.01;

Нужно написать функцию, которая считала бы количество знаков после запятой.

Строковые функции не хочется использовать. Думаю, они замедляют программу.
0.0001100110011001100110011- это начало двоичного представления очень простого в десятичной системе числа 0.1. Бесконечная периодическая дробь, которую в компьютере усекают. Интересующее Вас число знаков после запятой подсчитывается после перевода двоичного числа в десятичную систему счисления, в этом и состоит перевод в строку. Интересующее Вас свойство относится к параметрам строки, получаемой из компьютерного числа для показа людям. Можно, конечно, выдергивать из 8 байтов double по маске порядок, но, он дает положение первой значащей цифры, а Вам надо последнюю. Думаю, без перевода в строку никак нельзя. Еще о подводных камнях при использовании FPU для близких целей можно прочесть здесь https://habr.com/ru/post/537636/.
Перевод числа в строку с помощью FPU
Перевод числа в строку с помощью FPU
  • habr.com
Часто требуемое для вывода результатов расчетов преобразование числа с «плавающей точкой» из формата IEEE-754 в текстовую строку в «научной» нотации (т.е. с показателем степени «E») не является совсем уж тривиальной задачей. В силу обстоятельств автору пришлось самостоятельно «изобретать велосипед» такого преобразования. Причем хотелось сделать...
 
igrok333:
Через логарифм вот так

но только если в конце числа стоит единица

Работает и этот способ, но с оговоркой, что в старших разрядах нули, а младший разряд не более 3-х. Так что для 0.02 сойдет:

#property script_show_inputs

input double i_fValue = 0.02;                               // Real value
 
void OnStart()
{
   Alert("Digits: ", int(fabs(log10(i_fValue)) + .5));
}
 
Ihor Herasko:

Работает и этот способ, но с оговоркой, что в старших разрядах нули, а младший разряд не более 3-х. Так что для 0.02 сойдет:

к сожалению, не подойдет.
в старших разрядах нули. но в младшем разряде может быть любая цифра. от 1 до 9.


0.02
0.0005
0.00000008

 

Мой вариант:

//+------------------------------------------------------------------+
//| Double                                                           |
//+------------------------------------------------------------------+
int NumberOfDigitsAfterDecimal(double _val)
  {
   int count = 0;
//---
   double val =::MathAbs(_val);
   double c_val = val -::MathFloor(val);
   int fac_val = 10;
//---
   while (c_val > 0. && count < DBL_DIG)
     {
      c_val = val * fac_val;
      c_val = c_val - ::MathFloor(c_val);
      fac_val *= 10;
      count++;
     }
//---
   return count;
  }
//+------------------------------------------------------------------+
 
igrok333:
Есть переменная.
Например:
double а=0.02;

Нужно написать функцию, которая считала бы количество знаков после запятой.

Строковые функции не хочется использовать. Думаю, они замедляют программу.

такой вариант, но сочинил на ходу, не проверял с пристрастием

int Digits(double x) {
   if (x>=LONG_MAX || x<=LONG_MIN) return 0;
   int n=0;
   while (x!=(double)((long)x)) {
      x*=10;
      n++;
   }
   return n;
}
 

Кстати, никто не помнит, почему явное приведение к string обрубает 1 цифру?

void OnStart()
  {
   double val = 21.012345678901234; // 15 digits after decimal
   string val_str1 = DoubleToString(val, DBL_DIG);
   Print(val_str1);                 // 21.012345678901234
   string val_str2 = (string)val;
   Print(val_str2);                 // 21.01234567890123
  }


2021.01.18 23:46:06.801 с10 (EURUSD,H1) 21.012345678901234
2021.01.18 23:46:06.801 с10 (EURUSD,H1) 21.01234567890123
Документация по MQL5: Основы языка / Типы данных / Тип string
Документация по MQL5: Основы языка / Типы данных / Тип string
  • www.mql5.com
Тип string - Типы данных - Основы языка - Справочник MQL5 - Справочник по языку алгоритмического/автоматического трейдинга для MetaTrader 5