• 0

[VB.NET]Truncate without rounding


Question

So lets say I have a number, 16.95. I want it truncated to one decimal place, but NO ROUNDING. I want 16.9 for the final result.

So far I'm using:

Dim first As Int32 = Math.Floor(tp)
Dim second As Int32 = Int((tp - first) * 10)
Dim TPs As String = first & "." & second

It works for the following example, but not every time. I think only when there's already one decimal place. Another example:

tp = 16.7

first = 16

tp - first = 6.9999885559082 <---- do not understand

TP is a single, if that matters. I'm having a problem getting that one digit in the tenths place.

Link to comment
https://www.neowin.net/forum/topic/643336-vbnettruncate-without-rounding/
Share on other sites

6 answers to this question

Recommended Posts

  • 0

Dim tp As Single = 16.95

'Fix simply truncates the decimal whereas Math.Floor always rounds down
'  (e.g. Math.Floor(-16.95) = -17, but Fix(-16.95) = -16)
Dim first As Int32 = Fix(tp)
Dim second As Int32 = Int((tp - first) * 10)
Dim TPs As String = first &amp; "." &amp; second

tp = 16.95

first = 16

second = Int((16.95 - 16) * 10) = Int((.95) * 10) = Int(9.5) = 9

TPs = 16.9

For the record, it could be floating-point rounding errors. You might try using a Double rather than a Single.

Fix truncates. Int rounds down to the nearest integer less than or equal to itself, same as Math.floor IIRC. Other things like CInt and Round all use Banker's Rounding, which is a bit odd for some people... If you have a fractional part of .5 or less, the result rounds toward the nearest even integer. Otherwise, the result is rounded to the nearest integer.

Examples:

Using CInt on a value in the range -0.5 to 0.5 results in 0.

Using CInt on a value in the range -1.499999... to -0.500...001 or 0.500...001 to 1.499999... results in -1 or 1, depending on the sign.

Using CInt on a value in the range -2.5 to -1.5 or 1.5 to 2.5 results in -2 or 2, depending on the sign.

Using CInt on a value in the range -3.499999... to -2.500...001 or 2.500...001 to 3.499999... results in -3 or 3, depending on the sign.

Simply put, Banker's Rounding relies on that extra minute fractional piece to round to the appropriate integer. This is why I use Fix for everything - I don't have any issues with negative v.s. positive values like I would with Int or Math.floor or Math.ceiling or whatever. I also don't have rounding issues like with Round and CInt. Everything is predictable, in other words. Of course, the built-in Math.Round does a wonderful job of rounding "the normal way" already, so I suppose my reinventing the wheel using Fix is rather pointless. ^_^

Edited by rpgfan
  • 0

Truncate to 1 decimal place, no rounding:

Dim decimalNumber As Double = 16.95
Dim truncatedNumber As Double = Math.Truncate(decimalNumber * 10) / 10

Should work. Math.Truncate() gets the integral part of the number (the bit before the decimal point). Therefore, if you multiply that by 10, then truncate, and then divide after, you'll get the one decimal place without any rounding.

  • 0
So lets say I have a number, 16.95. I want it truncated to one decimal place, but NO ROUNDING. I want 16.9 for the final result.

tp = 16.7

first = 16

tp - first = 6.9999885559082 <---- do not understand

Single and double precision numbers are inherently approximative. It's very dangerous with such numbers, for instance, to compare 7 with 7 for equality: one could be 6.999999999 and the other 7.00000000001.

If you need exactitude, use integers only. Define a type that holds the number as an integer and a power of 10. But in most cases you should be fine with the built-in floats, doubles and decimals.

This topic is now closed to further replies.
  • Recently Browsing   0 members

    • No registered users viewing this page.
  • Posts

    • The problem of course is simply that government does not always know best. My point is that agency is taken away from the EU consumer in these cases. I'm sorry, but I do not believe that governments (politicians) are inherently good, and "looking out for me." Primarily they look to themselves and their own personal desires first, foremost, and always. When the EU or the DOJ fines these companies, claiming to "represent the welfare of the consumer," how much of these billion-dollar judgments are handed to the consumers they claim to represent? Not even a dollar, as I've seen. Yet the EUC lawyers who are paid to sit around and dream up these suits make huge commissions on the fines the EUC adjudicates, which is an ironclad fact I hope everyone is aware of. It's also rank corruption, of course, but that's another topic. Last, when the EU inflicts these judgments, or the DOJ, take your pick, the costs are bundled right along in the cost of the goods and services these companies provide the consumers they are "looking out for." If you are someone who believes his government is his savior then you have my condolences. I think Apple is right here, because the whole scheme of consumer choice is that consumers pick and choose among the products companies offer. Microsoft Windows is more compatible with third party software and hardware than any desktop OS on Earth, which is my sole reason for choosing it. Just because the EUC forces companies do certain things it knows the companies do not want to do, "or else", has no bearing on consumer benefit. This Siri thing is almost idiotic it's so infantile. But this is what the EUC does when the EU in Brussels becomes cash-strapped and needs a big infusion of cash. Some people get upset by "big companies" but it's the opposite when governments dwarf the size and scope of these companies, which is so obvious it hurts.... I mean you can't honestly believe that forcing Apple to do things with Siri it has its own reasons to decline is something that "opens up" Apple, do you? Say it aint' so...
    • Looks like many years since the request was made, a directory tree view finally may be added. https://github.com/files-community/Files/pull/18537
    • There's this from last year https://gist.github.com/threat...364659a8887841aa43deca4efd9 but nothing about a buffer overflow that MS somehow can't code against. No matter what, it makes sense to take a "protected by default" approach.
  • Recent Achievements

    • One Month Later
      sjbousquet earned a badge
      One Month Later
    • Week One Done
      sjbousquet earned a badge
      Week One Done
    • First Post
      DragonOfMercy earned a badge
      First Post
    • First Post
      bella52 earned a badge
      First Post
    • Reacting Well
      Techinmay earned a badge
      Reacting Well
  • Popular Contributors

    1. 1
      +primortal
      501
    2. 2
      PsYcHoKiLLa
      214
    3. 3
      +Edouard
      156
    4. 4
      Steven P.
      84
    5. 5
      FloatingFatMan
      72
  • Tell a friend

    Love Neowin? Tell a friend!