1

I should write a program that the input is double (variable called money), and I should print separately the digits before the decimal point and the digits after. for example:

for the input: 36.5 should print: The number before the decimal point is: 36 The number after decimal point is: 5

for the input: 25.4 should print: The number before the decimal point is: 24 The number after decimal point is: 4

Console.WriteLine("Enter money:");
            double money = double.Parse(Console.ReadLine());
            int numBeforePoint = (int)money;
            double numAfterPoint = (money - (int)money)*10;
            Console.WriteLine("The number beforethe decimal point is: {0}. the number after the decimal point is: {1}",numBeforePoint,numAfterPoint);

If I enter 25.4 it prints: The number before the decimal point is: 24 The number after decimal point is: 3.9999999

I don't want 3.999999 I want 4

Error 404
  • 427
  • 5
  • 25
  • 4
    You shouldn't use `double` for financial values - use `decimal`. Floating-point types are for scientific calculations. Different types have different precision. – xxbbcc Oct 16 '17 at 20:38
  • A hacky solution - You could use math.round... – AGrammerPro Oct 16 '17 at 20:38
  • 1
    @AGrammerPro Not hacky at all. Math.Round is commonly used to correct floating point precision errors such as this. – BradleyDotNET Oct 16 '17 at 20:44
  • @BradleyDotNET I mean it is 'hacky' because he should not be using a double. lack of wording on my part! – AGrammerPro Oct 16 '17 at 20:46
  • Why use any math types at all? All you care about is the presence of a certain character in the input. Treat it as a string all along and you don't have to worry about any sort of rounding errors. – Adam V Oct 16 '17 at 20:46

4 Answers4

3

You should use decimal to represent numeric types, rather than doubles - it's what they were designed for!

You've been the victim of a floating point error, where the value you're assigning to a floating point value can't be exactly represented with its precision (the .999... you get is the closest value it can represent).

decimals have a lower range than doubles, but much higher precision - this means they're more likely to be able to represent the values you're assigning. See here or the linked decimal documentation page for more details.

Note that a more conventional way of getting the decimal part involves Math.Truncate (which by the way will work for negative values as well):

decimal numAfterPoint = (money - Math.Truncate(money))*10;
hnefatl
  • 5,860
  • 2
  • 27
  • 49
2

Probably easiest to use the string representation of the decimal, and use substring before and after the index of '.'

Something like this:

string money = Console.ReadLine();
int decimalIndex = money.IndexOf('.');
string numBeforePoint = money.Substring(0, decimalIndex);
string numAfterPoint = money.Substring(decimalIndex + 1);

Then you can parse the string representations as needed.

akerra
  • 1,017
  • 8
  • 18
2

Try this:

static string Foo(double d)
        {
            var str = d.ToString(CultureInfo.InvariantCulture).Split('.');
            var left = str[0];
            var right = str[1];
            return $"The number before the decimal point is: {left} The number after decimal point is: {right}";
        }
halfer
  • 19,824
  • 17
  • 99
  • 186
taquion
  • 2,667
  • 2
  • 18
  • 29
0
using System.Linq;

public static string GetDecimalRemainder(double d)
{
    return d.ToString(CultureInfo.InvariantCulture).Split('.').Last();
{

Using LINQ is much more convenient in my opinion.

Ratatoskr
  • 189
  • 5