-4

I am looking to round a double to any arbitrary digit to right or left of the decimal point.

Math.Round only works for digits to the right of the decimal point, and I need to be able to round to values the nearest 10s, 100s, 1000s, ...

Example of desired inputs/outputs:

Round(1234.56789,  0) == 1235
Round(1234.56789, -3) == 1234.568
Round(1234.56789,  3) == 1000

This problem differs from Round double in two decimal places in C#? because I need to round values to positions to the left of the decimal point such as 1,2345,000 rounding to the nearest 10,000

Nifim
  • 3,437
  • 11
  • 21
  • 1
    double's can't represent numbers with a finite number of decimal digits exactly, even when those numbers are within the min and max values, so this isn't *possible* to be solved with a `double`. – Servy Feb 24 '21 at 19:18
  • Consider using the [Decimal](https://docs.microsoft.com/en-us/dotnet/api/system.decimal?view=net-5.0) type if you need a fixed point number type. Otherwise, do you need to round this for display purposes, or for calculations? It's usually an error to round off values before you are finished computations with them, so can we deduce that this is for display only? (ie: do you want a string as output?) – J... Feb 24 '21 at 19:23
  • @J... in this case i am rounding a value after adding a `correction` to a reading, the correction introduces excess precision that my team metrologies wants rounded off. a Decimal is possible a more appropriate type, but my values are no smaller than `1e-9` and no large than `1e+6` – Nifim Feb 24 '21 at 19:35
  • 1
    @Nifim I'll ask again - are you rounding after the correction **for use in further calculations**? Or are you rounding after the correction for *display purposes* (ie: do you want a string as output?). I'm not sure how a "correction" can add "excess precision", to be honest. That sounds like a wrong notion all around. – J... Feb 24 '21 at 19:40
  • @J... it is to produced the final value, no further calculation is done to the value after it is rounded, it is simply stored for future reference. All to the request of my metrology department. – Nifim Feb 24 '21 at 19:43
  • @Nifim Stored... in a database? In a DOUBLE field? Why not store it in full precision? You can format a rounded string for display when you need to show it to someone. If you're somewhere with a metrology department, it seems odd that you would discard the true calculation result in favour of a truncated approximation... – J... Feb 24 '21 at 19:46
  • stored as text report, printed off and put in a filing cabinet... no joke – Nifim Feb 24 '21 at 19:48
  • Also : [How do I display a decimal value to 2 decimal places?](https://stackoverflow.com/q/164926/327083) – J... Feb 24 '21 at 19:50
  • No it does not, because i need to also round `1234` to `1000` – Nifim Feb 24 '21 at 19:50
  • Also : [Round a double to x significant figures](https://stackoverflow.com/q/374316/327083) – J... Feb 24 '21 at 19:51
  • Also some good answers here (if you want text) : [Formatting numbers with significant figures in C#](https://stackoverflow.com/q/158172/327083) – J... Feb 24 '21 at 19:52
  • Note the keyword that you're missing is "[significant figures](https://en.wikipedia.org/wiki/Significant_figures)" - this is what scientists use to mean what you're talking about. – J... Feb 24 '21 at 19:55

1 Answers1

0

If we take 10 to the power of the digit position, we can round the double to the arbitrary precision

public double RoundToDigit(double i, int digitPosition)
{
    double precision = Math.Pow(10, digitPosition);

    double result = Math.Round(i / precision, 0) * precision;

    return result;
}
Nifim
  • 3,437
  • 11
  • 21
  • 1
    Why not `double precision = Math.Pow(10, digitPosition); double result = Math.Round(i / precision, 0) * precision;` ? On provided data it seems to produce correct results – Guru Stron Feb 24 '21 at 19:10
  • @GuruStron initial I thought it would give me less precision, but looking at it now... I don't know why I thought that – Nifim Feb 24 '21 at 19:14
  • @Magnetron `(floor / 2)` is added to the initial value so `19` becomes `24` and be floored to `20` – Nifim Feb 24 '21 at 19:39
  • Oh, missed that line, sorry – Magnetron Feb 24 '21 at 19:51