0

Can anyone give me an easy way to find out the numbers after the decimal point of the double?
All i need to do is to find out if the number ends in 0 like 1.0 or 10.0 or 323.0 ?

Have you any idea about this?

Chuck Norris
  • 15,207
  • 15
  • 92
  • 123
AltF4_
  • 2,312
  • 5
  • 36
  • 56
  • well the number in question might be 10.04 for example in which case it doesnt intrest me .... JUST 0 after the point – AltF4_ May 18 '12 at 15:13
  • are you basically saying you want to find out if the double is a whole number or not? – Chris May 18 '12 at 15:19
  • that is correct and want to then return that number as a string. AS IT WAS ENTERED – AltF4_ May 18 '12 at 15:29
  • Right. If you are looking at data entry then you most likely have a string. Just save that string and use the checks mentioned below and if its a whole nunmber return the string. I'm not sure why you would want to do this though. Usually you want to either display a standard number of decimal places for all numbers (eg `ToString("N2")`) or you want to return the number in its simplest form (which `ToString()` I think usually does). You probably want to edit the above question to be more clear on what you start with and what you want to end up with. – Chris May 18 '12 at 15:47

8 Answers8

3

Do you mean something like:

if (x == Math.Floor(x))

? Note that usually with binary floating point arithmetic, you want to have some sort of tolerance, so that 10.000001 was treated as "pretty close to 10". For example:

if (x - Math.Floor(x) < Tolerance)
{
    ...
}
Jon Skeet
  • 1,421,763
  • 867
  • 9,128
  • 9,194
  • 1
    If you have negative numbers that second one can do funny things (eg `Math.Floor(-10.00000001)` is `-11` because it always rounds down... – Chris May 18 '12 at 15:17
  • whay does this return a whole number if it hasnt got an .0 as just the number it self like if the number in question is 10 it returns 10D – AltF4_ May 18 '12 at 15:17
  • 1
    @AshShafiee: It's not clear to me what you mean. There's no difference between 10 and 10.0 in `System.Double`. – Jon Skeet May 18 '12 at 15:18
  • well I somehow need to be able to find out the difference between the 10.0 and 10 and return then as a string as they are ... hope thats clearer... – AltF4_ May 18 '12 at 15:26
  • @AshShafiee: They're the same value in `double` - and if you want to treat them differently, you probably shouldn't be using `double` to start with. What are these values meant to be representing? Perhaps you should be using `decimal`. – Jon Skeet May 18 '12 at 15:28
  • well its set in the database as double and I cant change that otehrwise I would ... lol spent all day on this little problem. These numbers are not neccessarily numbers... could be anything ... but if they are of type double and also have a .0 attached behind them I need to then represent that value in astring as it is ... – AltF4_ May 18 '12 at 15:32
  • 2
    @AshShafiee: If they're of type `double` then they clearly *are* necessarily numbers (or NaN values, I guess). It's not like they can be anything else. – Jon Skeet May 18 '12 at 15:33
  • when I do .ToString .0 gets dropped – AltF4_ May 18 '12 at 15:33
  • 4
    @AshShafiee: Yes, because it's fundamentally not part of the number. 1 and 1.0 and 1.00 are all represented the same way in a `double`. If you want to distinguish between them, **you can't use double**. This may mean you've got a fundamental design problem, of course... – Jon Skeet May 18 '12 at 15:42
3

Just use the Mod operator, like so:

If (x Mod 1) = 0 Then
    ' Do some stuff
End If

(see http://en.wikibooks.org/wiki/Visual_Basic_.NET/Arithmetic_operators)

Harry Cutts
  • 1,352
  • 11
  • 25
  • what if I had 10 ??? or just 11 ???? i need to return them as they are .... but if I had 10.0 then it takes the 0 off so it retuns just 10? – AltF4_ May 18 '12 at 15:19
  • 2
    @Ash: this is not to do with the double. If you had a double that was 10.0 and you took the .0 off somehow then you'd get the exact same number. The .0 will only come from how you are formatting it when you convert it to a string. – Chris May 18 '12 at 15:20
  • 1
    What are you actually trying to do here? It sounds to me as if you're looking for a way to _present_ the number to the user. In that case, I'd suggest looking at [number format strings](http://msdn.microsoft.com/en-us/library/dwhawy9k.aspx). These provide you with a way to present the number when you put it in a string. – Harry Cutts May 18 '12 at 15:45
3

What you need to do is multiply by 10 and then mod 10.

For instance. lets say x = 10.2

temp = x * 10 ' temp equals 102

temp = temp % 10 ' that should return the 2. Temp is now the value of the decimal you need.

This should work for negative values as well.

If you need to compare to see if it is a 0, all you do is compare your temp var to 0.

Tony318
  • 552
  • 2
  • 9
  • I need to get different result if my number is 10 or 10.0 ... have you got a way of doing that ??? – AltF4_ May 18 '12 at 15:36
  • I'm guessing this number is coming from a file or textbox and is dependent on how it is entered by a user? You could convert the decimal to a string, then search for a '.' After that setting a bool so that if there is a decimal use my example, if not, use whatever return you need for an integer value. – Tony318 May 18 '12 at 15:46
2

If you are using any of the numeric data types (e.g. double, single, integer, decimal), you cannot represent 10.0 and 10 as two different and distinct values. There is no way to do that. If you need to keep the mantissa of the number, even when it is zero, you will have to store the value as some other data type such as a string.

To validate a string that has been entered, you could do something like this:

Public Function MantissaIsZero(ByVal value As String) As Boolean
    Dim result As Boolean = False
    Dim parts() As String = value.Split("."c)
    If parts.Length = 2 Then
        Dim mantissa As Integer = 0
        If Integer.TryParse(parts(1), mantissa) Then
            result = (mantissa = 0)
        End If
    End If
    Return result
End Function
Steven Doggart
  • 43,358
  • 8
  • 68
  • 105
  • OK ... any other suggestion beside the String ... becuase thats whats ruining the number .... how about decimal ? – AltF4_ May 18 '12 at 15:43
  • 1
    @AshShafiee: any numeric format (double, single, decimal, etc.) will treat the number 10.0 and 10 the same. The only format that won't is a string or similar equivalent. The obvious reason being that its only in a string that there is actually a difference between the two. Can you explain why you think the string is ruining the number or what you mean by that? – Chris May 18 '12 at 15:56
  • @AshShafiee In what way is the string data type ruining the number? As Chris said, you'll have the same issue with any numeric format. If you need a precise number, decimal is a good choice, rather than a floating point data type, but it doesn't sound like that's your concern right now. – Steven Doggart May 18 '12 at 15:59
  • 1
    This is really your best bet. If you need to store the value into a temporary variable for conversion sake so that you don't lose the double value. With using any sort of numeric datatype though it isn't possible to get a difference between 10 and 10.0 because they are the same number. To a string datatype they are completely different values though. – Tony318 May 18 '12 at 17:20
1

Try this function:

Function CalculateDecimals(input As Double)
  Dim positiveInput As Double
  positiveInput = Math.Abs(input)
  Return positiveInput - Math.Floor(positiveInput)
End Function

It will give you the decimals you are looking for.

Use it in this way:

If (Math.Abs(CalculateDecimals(yourNumber))<0.00001) Then ...
Chaim Zonnenberg
  • 1,793
  • 13
  • 10
1

If your input is a string, and you want to identify strings that have decimals, but where those decimal places are all zero, then you could use a regular expression:

var regex = new Regex("^-?\\d+\\.0+$");
if (new Regex.IsMatch(input))
{
    // it's in the format you want
}
David M
  • 71,481
  • 13
  • 158
  • 186
0

Here is something you can try. Converting the double to an int removes the decimal place. Then you can do a Mod operation on the same number get the remainder equal to what is in the decimal place.

(double)(4.9 % (int)(4.9))
Ryan
  • 1
0

It's been a while, nevertheless my solution:

I also used the mod function, but you have to be careful with that as there are precision "problems" with the data type 'Double':

Dim numberDbl As Double = 1.2
Dim modValDbl As Double = 1.0
Dim remValDbl As Double = numberDbl Mod modValDbl
'remValDbl = 0.19999999999999996 -> not 100% precise

Dim numberDec As Decimal = 1.2D
Dim modValDec As Decimal = 1D
Dim remValDec As Decimal = numberDec Mod modValDec
'remValDec = 0.2 -> correct

Therefore I wrote this function: (example: number = 1.25)

  • I first take the parameter number and mod it with its own integer (1.25 mod 1)
  • so I get the decimal value of my number and store it to remVal = 0.25
  • in the loop I keep multiplying remVal with 10 and compare this value with the same truncated value (i.e.: 2.5 <> 2) until they are the same
  • with every loop I increment the multiplier by 10
  • as soon the two values match (i.e.: 25 = 25) I can return my decimal value using remVal and multiplier

    Public Shared Function getDecimalPlaces(number As Double) As Double
    Dim modVal As Integer = CInt(If(Math.Truncate(number) = 0, 1, Math.Truncate(number)))
    Dim remVal As Decimal = CDec(number) Mod modVal
    Dim retVal As Double = 0
    
    Debug.WriteLine("modVal: " + modVal.ToString)
    Debug.WriteLine("remVal: " + remVal.ToString)
    Dim multiplier As Decimal = 1
    
    While remVal * multiplier <> Math.Truncate(remVal * multiplier)
        Debug.WriteLine("remVal * multiplier <> Math.Truncate(remVal * multiplier): " + (remVal * multiplier).ToString + " <> " + (Math.Truncate(remVal * multiplier)).ToString)
        multiplier *= 10
        Debug.WriteLine("remVal * multiplier <> Math.Truncate(remVal * multiplier): " + (remVal * multiplier).ToString + " <> " + (Math.Truncate(remVal * multiplier)).ToString)
    End While
    
    retVal = CDbl(remVal * multiplier)
    
    Debug.WriteLine("remVal: " + remVal.ToString)
    Debug.WriteLine("multiplier: " + multiplier.ToString)
    Debug.WriteLine("retVal: " + retVal.ToString)
    Return retVal
    End Function
    
    'Output with number = 1.25
    'modVal: 1
    'remVal: 0,25
    'remVal * multiplier <> Math.Truncate(remVal * multiplier): 0,25 <> 0 -> true
    'remVal * multiplier <> Math.Truncate(remVal * multiplier): 2,50 <> 2 -> true
    'remVal * multiplier <> Math.Truncate(remVal * multiplier): 2,50 <> 2 -> true
    'remVal * multiplier <> Math.Truncate(remVal * multiplier): 25,00 <> 25 -> false: exit while
    'remVal: 0,25
    'multiplier: 100
    'retVal: 25
    
Guti_Haz
  • 2,528
  • 2
  • 15
  • 20