Alexey Oreshkin: ну и что. Мы говорим о разных вещах. Приведённая мною функция считает количество знаков после запятой, а не кратность одного числа другому.
Ваша функция правильно работает только со значениями типа 0.1, 0.01 и т.д. Такой результат можно получить без цикла, через логарифм.
Задача определить число знаком после запятой у любого числа.
В Code Base у меня есть вариант функции, определяющей количество десятичных знаков после запятой (количество знаков в дробной части).
При необходимости можно и на её основе что-то делать.
А это набросала сейчас пример из "на коленке" (функция из Code Base взята "как есть"):
//+------------------------------------------------------------------+//| test.mq4 |//| Copyright 2015, MetaQuotes Software Corp. |//| https://www.mql5.com |//+------------------------------------------------------------------+#property copyright"Copyright 2015, MetaQuotes Software Corp."#property link"https://www.mql5.com"#property version"1.00"#property strict//---#define TEST_PRINT_TWO(x,y) Print(__LINE__,", ",__FUNCTION__,", ",(#x)," = ",(x),", ",(#y)," = ",(y))
//+------------------------------------------------------------------+//| Script program start function |//+------------------------------------------------------------------+voidOnStart()
{
string symbol=Symbol();
//---double lotstep=MarketInfo(symbol,MODE_LOTSTEP); // шаг изменения размера лотаint count=GetQuantDigits(lotstep);
//---
TEST_PRINT_TWO(DoubleToString(lotstep),IntegerToString(count));
}
//+------------------------------------------------------------------+//|GetQuantDigits - функция для определения количества дробных чисел |//|(количество десятичных знаков) |//+------------------------------------------------------------------+//|2015, Dina Paches (последнее изменение 25.09.2015) |//+------------------------------------------------------------------+int GetQuantDigits(constdouble val,//число типа doubleconstint digits=8)
{
int res=digits;
if(res<1 || res>8)
{
Print(__LINE__,__FUNCTION__," Error code. digits <1 or >8.");
res=-1;
return(res);
}
//---если число = 0, то выходимif(NormalizeDouble(val,digits)==0)
{
res=0;
return(res);
}
//---double val_abs=val;
double val_floor=0;
//---если число < 0, сделаем его для расчётов положительнымif(NormalizeDouble(val_abs,digits)<0)
{val_abs=MathAbs(val_abs);}
//---выделим из числа целое значение
val_floor=MathFloor(val_abs);
//---выделим из числа значения после десятичной точки
val_abs=NormalizeDouble(val_abs-val_floor,digits);
//---если после десятичной точки нули, то выходимif(NormalizeDouble(val_abs,digits)==0)
{
res=0;
return(res);
}
//---если дошли сюда, значит есть цифры кроме 0 после десятичной точки.//---преобразуем числа после десятичного знака в целое числоint val_pow=(int)MathPow(10,digits);
int val_res_dig=(int)(NormalizeDouble(val_abs*val_pow,0));
//---а теперь преобразуем это целое число в текстstring text=IntegerToString(val_res_dig);
//---определим длину полученного текстаint lengh=StringLen(text);
//---определим количество десятичных знаковfor(int i=lengh-1;i>=0;i--)
{
if(StringFind(text,"0",i)==i)
{res=res-1;}
else {return(res);}
}
//---return(res);
}
//+------------------------------------------------------------------+
int fun(double ch)
{
int i = 0;
double res = 0, ostatok = fmod(ch, 1);
while(ostatok != 0 && i < 16) // число взято от фонаря для прерывания зацикленности
{
res = ostatok * 10;
ostatok = NormalizeDouble(fmod(res, 1), 8); // Вроде 8 максимально
i++;
}
return(i);
}/*******************************************************************/
ну и что. Мы говорим о разных вещах. Приведённая мною функция считает количество знаков после запятой, а не кратность одного числа другому.
Ваша функция правильно работает только со значениями типа 0.1, 0.01 и т.д. Такой результат можно получить без цикла, через логарифм.
Задача определить число знаком после запятой у любого числа.
Ваша функция правильно работает только со значениями типа 0.1, 0.01 и т.д. Такой результат можно получить без цикла, через логарифм.
Задача определить число знаком после запятой у любого числа.
Заинтриговал прям. Пойду проверю.
функция не моя, не проверял :)
int foo(float f, int level = 0) { if (level > FLT_DIG) { return FLT_DIG; } if (f < 0) { return foo(-f); } if (f < 1) { return foo(f + 1); } f -= round(f); if (fabs(f) <= FLT_EPSILON) { return level; } return foo(f * 10, level + 1);}
функция не моя, не проверял :)
}
Ну ничего себе, вот это завернуто.
знак числа - учитывается
максимальное кол-во знаков - учитывается
эпсилон - учитывается
должна работать ?
знак числа - учитывается
максимальное кол-во знаков - учитывается
эпсилон - учитывается
должна работать ?
Ваша функция правильно работает только со значениями типа 0.1, 0.01 и т.д. Такой результат можно получить без цикла, через логарифм.
Задача определить число знаком после запятой у любого числа.
Пойду думать как сделать функцию для любого числа.
В Code Base у меня есть вариант функции, определяющей количество десятичных знаков после запятой (количество знаков в дробной части).
При необходимости можно и на её основе что-то делать.
А это набросала сейчас пример из "на коленке" (функция из Code Base взята "как есть"):
Записи в журнале "Эксперты":
И вот ещё один вариант.
Не долго проверялось, но вроде работает.
Dmitry Fedoseev:
Должна, но не работает. Отдаю 0.1, получаю 0.
Функция написана на С
На mql5 действительно выдает 0.
А на C# выдает 1.
Может mql кривой?
using System; using Microsoft.VisualStudio.TestTools.UnitTesting; namespace test { [TestClass] public class TstDeg{ const int DBL_DIG = 16; const double DBL_EPSILON = Double.Epsilon; [TestMethod] public void TestMethod1() { double a = 0.1; int deg = foo(a); } int foo(double f, int level = 0) { if (level > DBL_DIG) { return DBL_DIG; } if (f < 0) { return foo(-f); } if (f < 1) { return foo(f + 1); } f -= Math.Round(f); if (Math.Abs(f) <= DBL_EPSILON) { return level; } return foo(f * 10, level + 1); } } }