You can try this ... But I can’t guarantee anything ... I wrote and tested after 20 minutes and based on the Pyrolistic code from fooobar.com/questions/72830 / ... There is a big difference in that it uses long for a variable shifted (since a double has an accuracy of 15-16 digits and long is 18-19, so long enough), while I use decimal (because decimal has an accuracy of 28-29 digits).
public static decimal RoundToSignificantFigures(decimal num, int n) { if (num == 0) { return 0; }
If you do not trust (int)Math.Ceiling(Math.Log10((double) , you can use this:
private static readonly decimal[] Pows = Enumerable.Range(-28, 57) .Select(p => (decimal)Math.Pow(10, p)) .ToArray(); public static int Log10Ceiling(decimal num) { int log10 = Array.BinarySearch(Pows, num); return (log10 >= 0 ? log10 : ~log10) - 28; }
I wrote it after another 20 minutes (and yes, I tested all Math.Pow((double), p) for all values -28 - +28). It seems to work and it is only 20% slower than the C # formula based on double s). It is based on a static array of guidance and BinarySearch . Fortunately, BinarySearch already “offers” the following element when it cannot find one :-), so Ceiling is free.
source share