-2

I have the following code:

var voucherAmountValue = "5";
var totalValue = Math.Round(Convert.ToDecimal(voucherAmountValue), 2);

When I write totalValue to the console, it prints 5. I'd expect the fractional digits to be added, printing 5.00 for totalValue, but it doesn't: it still prints 5.

How can I add the fractional digits to a decimal that doesn't have them?

MrSilent
  • 564
  • 10
  • 28

3 Answers3

3

The problem here is that Math.Round does not add fractional digits, it only limits them.

Test this:

decimal a = 5m;
decimal b = Math.Round(a, 2); // b will be 5
a = 5.00m;
b = Math.Round(a, 3); // b will be 5,00 (not 5,000)
b = Math.Round(a, 2); // b will be 5,00
b = Math.Round(a, 1); // b will be 5,0

As you can see, if the original string contains just "5", then the decimal value will also be just 5, and calling Math.Round(..., 2); will only limit the fractional digits down to 2, it will not add missing fractional zeroes if less than 2.

You can fix this by explicitly evaluating an expression that will force the creation of these digits:

var totalValue = Math.Round((Convert.ToDecimal(voucherAmountValue) / 100.0m) * 100.0m, 2);
Lasse V. Karlsen
  • 380,855
  • 102
  • 628
  • 825
2

use

var totalValue = ((decimal)voucherAmountValue/100)*100;
amit dayama
  • 3,246
  • 2
  • 17
  • 28
  • 1
    Why would that produce anything different? The OP's problem is *formatting* the value, not rounding. Besides, this won't even round the number. If the original number had 5 decimals, the result will still have 5 decimals – Panagiotis Kanavos Nov 05 '15 at 11:32
  • @PanagiotisKanavos Try it yourself, it does actually work. `((5m/100)*100).ToString()` returns `"5.00"`. (As for your edited comment, yeah, `Math.Round` is still needed to round off excess precision.) –  Nov 05 '15 at 11:34
  • var voucherAmountValue = 5; var totalValue = ((decimal)voucherAmountValue/100)*100; System.Console.WriteLine(totalValue+""); @PanagiotisKanavos: you may try the above code – amit dayama Nov 05 '15 at 11:35
  • 3
    Just because some code accidentally produces the result doesn't make it correct, especially when it includes needless operations. A simple `decimal.ToString("N2")` would produce the correct string – Panagiotis Kanavos Nov 05 '15 at 11:40
  • But he's not interested in the string, he's interested in having the decimal value be correct to begin with. `decimal` types behaves differently from `double` and `float` in that they know how many fractional digits they're actually representing. In a `decimal`, `5` and `5.00` is *not* the same value, they may compare equal, and you can certainly format them to a string that would be equal, but the actual value is not. – Lasse V. Karlsen Nov 05 '15 at 11:40
  • This solved my problem var voucherAmountValue = _commandsManager.GetDisplayText(); var totalValue = (Convert.ToDecimal(voucherAmountValue) / 100) * 100; – MrSilent Nov 05 '15 at 11:41
  • @AlexandruMitu what problem do you think it solved? The number was correct to begin with! Besides, did you try it with a value with many decimals, eg 5.567? – Panagiotis Kanavos Nov 05 '15 at 11:41
  • @PanagiotisKanavos No, it wasn't. Please check the difference between `decimal a = 5.00m;` and `decimal a = 5.0m;`. The two values will know they represent 2 fractional digits and 1 fractional digits. He's converting *from* a string, but he's not asking how to convert *to* a string, he's asking how to get the right decimal value. – Lasse V. Karlsen Nov 05 '15 at 11:42
  • well.. if you try for 5.678 it would give output as 5.67800 but if you want result as 6.00 (for 5.678)>> var totalValue = ((decimal)Math.Round(voucherAmountValue)/100)*100; will do the trick – amit dayama Nov 05 '15 at 11:45
  • @PanagiotisKanavos Yes, I do have more code than the one I've provided and it is fine now, I am getting 5.00 instead of 5 on my customer display. – MrSilent Nov 05 '15 at 11:45
0

As I understand you have an integer value. So to round and to have an remainder, try this code:

int k = 5;
var totalValue = Math.Round(Convert.ToDecimal(k)).ToString(".00");

This second row of code means:

  1. integer value k converts to float

  2. Round() method of static class Math rounds a value to the nearest integer or to the specified number of fractional digits.

  3. ToString(".00") means converting to string type. .ToString(".00") means that you will always see if there are nulls. If you do not want to see nulls, use this .ToString(".##");
StepUp
  • 36,391
  • 15
  • 88
  • 148
  • The input is *text*, not int. If it were, the value wouldn't need rounding. The text must be parsed using the appropriate culture first, then formatted to a string. It probably is something like `1234.567` or `123,456` – Panagiotis Kanavos Nov 05 '15 at 11:38
  • @PanagiotisKanavos "voucherAmountValue will have the value of 5 and totalValue should have the value of 5.00 but it also has the value 5". As I understand OP wants to add nulls after the number. – StepUp Nov 05 '15 at 11:47