Round to Even (aka Banker''s Rounding) - The final function

  • We all agree. The rules have been laid out exactly, and no one other than you disagrees with them.

  • So, you two agree on what?

    Which result of Banking Rounding of 612.945 is right and which is wrong:

    612.94 or 612.95 ?

    Is there an implementation of the BR function which works correctly with any supplied value and ALWAYS returns expected result?

    Also, you still fail to provide implementation returning right result for this:

    DECLARE

    @enumerator DECIMAL(38, 12)

    ,@denominator DECIMAL(38, 12)

    SELECT

    @enumerator = 5

    ,@denominator = 111.111

    SELECT @enumerator/@denominator,

    dbo.fn_BRound2(@enumerator/@denominator, 2)

    ,Round(@enumerator/@denominator,2)

    Not so good in programming?

    Need some help from professionals?

    _____________
    Code for TallyGenerator

  • This is easy. The exact number 612.945, if followed by no non-zero digits, should round down to 612.94. The number that the function received in the tests was actually 612.94500000000005, which should round up to 612.95. But you knew that already, as you picked that number specifically for that reason. No problem, as the function performs as per the rules, based on the data it receives. Just like the internal Round() function, which I proved was just as susceptible to SQL Server's floating point anomalies, which has nothing to do with the concept of Banker's Rounding.

    I'll bet you that all David's contributing to this thread, as well as anyone else who has been contributing (I was going to say except Sergiy, but I don't yet consider what you've been doing to be contributing), will agree that that is how the Banker's rounding concept is documented, and that the two returned values were exactly what one should expect based on the exact value received by the function.

    Want to take that bet?

  • I know how 612.945 should be rounded by BR.

    But it's not.

    Can you get right result from your BR function for value 612.945?

    Is your implementation valid?

    I guess this topic is about valid implementation, not about theory.

    Right?

    So, keep to the topic.

    _____________
    Code for TallyGenerator

  • Implementation is fine for what it was designed for, which is floats, which as both you and I know (it's not like we haven't pointed it out repeatedly), is the problem with 612.945. Due to SQL Server's floating point implementation issues, it is being converted into a higher number, thus rounding up (properly, based on what the function is working with at that point). As was stated several times already, we are going to create a decimal version of it as well, to avoid the floating point errors which SQL Server adds to the mix, and that should be used when the passed value isn't a float. As demonstrated previously, this isn't due to the Banker's Rounding function, as Round() suffers from the same issue when dealing with DOUBLE PRECISION numbers.

    If the parameter received is a decimal, then it will happily return 612.94 for the number 612.945. At this point, I'm not particularly concerned about that, as I'd rather us nail the float version first (which I think is likely already the case, but want to do more testing), then make a modified version of the final function for decimal numbers.

    For some odd reason, you also keep using the fn_BRound2 function, when it was pointed out to you on the very first page that that's not what we're working on.

    Now, if you actually find a problem where the floating point value that the fn_BRound function is receiving via the parameter is not being rounded properly, feel free to demonstrate it.

  • But I need to round 612.945!

    Is it impossible task for your BR implementation?

    _____________
    Code for TallyGenerator

  • Oh, I didn't know you just needed the answer so badly that it required an exclamation point. In Banker's rounding, to 2 digits scale, it's 612.94, to 1 digit, it's 612.9, and with 0 digits scale it's 613, which the stated rules make quite clear. Glad I could help out.

    If you'd rather do it programatically, either wait for the floating point version to be tested, so we can simply change the datatypes and have a decimal version which will happily return 612.94 when passed the exact numeric 612.945, or actually implement it yourself if you don't want to wait. It's pretty easy to do, and if I was 100% satisfied that the floating point version was done, I or someone else would have already done it. If you find it too difficult, someone on this board will happily help with the programming, as that's what this board is for. I have faith that you are "The Little Engine that Could" of the SQL Server world. Just keep repeating "I think I can, I think I can!", and before you know it, you'll be able to correctly answer the questions (with the occasional mistakes that we all make) that others pose here.

    We have faith in you!

  • So, which version of BR you suggest to use?

    Which one will return consistently right results?

    _____________
    Code for TallyGenerator

  • "So, which version of BR you suggest to use?"

    The appropriate one.

    "Which one will return consistently right results?"

    Both, when used in the appropriate situations.

    Much like I don't try to cast a city name to an integer, I don't try to pass exact numerics and approximate numerics back and forth and get consistent results. It's a programmer thing, so don't feel bad about not understanding. To help you move forward in your learning process, I'll quote an appropriate passage from BOL, to save you having to learn how to navigate that tool.

    "The IEEE 754 specification provides four rounding modes: round to nearest, round up, round down, and round to zero. Microsoft® SQL Server™ uses round up. All are accurate to the guaranteed precision but can result in slightly different floating-point values. Because the binary representation of a floating-point number may use one of many legal rounding schemes, it is impossible to reliably quantify a floating-point value."

    Oh look, they not only talk about the problems of floating-point values, they even mention banker's rounding.

    Once again, happy to help answer your questions to further you along with your learning. That's what we're here for.

  • I'm thrilled to see that "programmer thing" which changes data type of incoming parameter depending on the value supplied.

    David? I tried to stop you, but you continue to expose your incompetence.

    And, sorry, stupidity.

    You don't even understand how the quote you posted makes laugh at BR definition.

    What "exactly half way" you're talking about if "All are accurate to the guaranteed precision", if "it is impossible to reliably quantify a floating-point value"?

    If it can fit to your brain, of course.

    Yeah, really appropriate passage from BOL.

    It's not BOL, it's LOL!

    _____________
    Code for TallyGenerator

  • Remember, we created a whole thread for you to take a dump in. This one isn't it.

  • Hear Hear.  Back to the plot

    I've had a look around and found this page contains lots of information, and has lots of links at the bottom to other sites, including this one, which talks about ulps and the like.  As I've said, I'm no mathmatician, but I think a bit of research cant hurt.

    Dave J


    http://glossopian.co.uk/
    "I don't know what I don't know."

  • No need for much of investigation.

    Just a bit.

    "There are two reasons why a real number might not be exactly representable as a floating-point number. "

    One reason would be enough.

    Function which accepts only "precise" values cannot have FLOAT as parameter datatype.

    Because there is one or more reasons "why a real number might not be exactly representable as a floating-point number".

    David McFarland, I told you, your implementation sucks.

    Thanks David Jackson for confirmation.

    So, where is BR function good emough to perform rounding of 50/111.111 correctly?

    _____________
    Code for TallyGenerator

  • Hey Threadshitter, remember we have another thread for that purpose. One, it's not my implementation. Two, it's actually pretty close to perfect (I think it's already there for floating point parameters), and far better than your "fixed" implementation, which doesn't work properly.

    We discussed the need for a function for approximate numerics and exact numerics, over and over again, but are trying to get the approximate numeric version working first. I think David Jackson's version is complete, but haven't finished testing.

     

  • Yes, David, I see, you getting frustrated, because you've got nothing to say.

    Sorry for you. I warned you.

    Now, instead of admitting you're wrong you just making stupid lies:

    1) It's your implementation as well. You put your sign on it;

    2) "Close to perfect" means what? Almost pregnant? Solution either works or not. "Almost works" means it does not;

    3) I never made any implementation. I stated there could not be any right implmentation because the concept is wrong. So, my implementation is no implementation.

    4) BR is based on assumption of absolute precision of supplied parameters. "Exacly half way" - remember? So, what a "approximate numeric version" you are talking about? If you would be at least a trained programmer you would know that there could not be any "approximate numeric" solution to "precise numeric" task. They just don't match.

    When you finish your testing feel free to post you results.

    If you wish to get next session of lashing.

    _____________
    Code for TallyGenerator

Viewing 15 posts - 46 through 60 (of 378 total)

You must be logged in to reply to this topic. Login to reply