Results 1 to 10 of 10

Thread: divide bug?

  1. #1

    Thread Starter
    Fanatic Member
    Join Date
    May 2001
    Posts
    837

    divide bug?

    How come CInt(750 / 100) = CInt(850 / 100)?

    They both equal 8...how is that possible? and how would i emulate this weird formula evaluation in C++?

    I'm trying to convert some VB code (that works perfectly) to C++ and this is a bug I tracked down. C++ evaluates static_cast<long>(750 / 100) = 7, static_cast<long>(850 / 100) = 8
    The human brain cannot hold all of the knowledge that exists in this world, but it can hold pointers to that knowledge.

  2. #2
    Ex-Super Mod RobDog888's Avatar
    Join Date
    Apr 2001
    Location
    LA, Calif. Raiders #1 AKA:Gangsta Yoda™
    Posts
    60,709
    You need to use a double converter.
    VB Code:
    1. Option Explicit
    2.  
    3. Private Sub Command1_Click()
    4.     MsgBox CDbl(750 / 100) '= 7.5
    5.     MsgBox CDbl(850 / 100) '=8.5
    6.     MsgBox CDbl(750 / 100) = CDbl(850 / 100) '=False
    7. End Sub
    VB/Office Guru™ (AKA: Gangsta Yoda®)
    I dont answer coding questions via PM. Please post a thread in the appropriate forum.

    Microsoft MVP 2006-2011
    Office Development FAQ (C#, VB.NET, VB 6, VBA)
    Senior Jedi Software Engineer MCP (VB 6 & .NET), BSEE, CET
    If a post has helped you then Please Rate it!
    Reps & Rating PostsVS.NET on Vista Multiple .NET Framework Versions Office Primary Interop AssembliesVB/Office Guru™ Word SpellChecker™.NETVB/Office Guru™ Word SpellChecker™ VB6VB.NET Attributes Ex.Outlook Global Address ListAPI Viewer utility.NET API Viewer Utility
    System: Intel i7 6850K, Geforce GTX1060, Samsung M.2 1 TB & SATA 500 GB, 32 GBs DDR4 3300 Quad Channel RAM, 2 Viewsonic 24" LCDs, Windows 10, Office 2016, VS 2019, VB6 SP6

  3. #3

    Thread Starter
    Fanatic Member
    Join Date
    May 2001
    Posts
    837
    Can't. The original code is some complex compression algorithm written by someone else. Unless you know of some good free C++ JPEG compression code that takes a byte stream and spits another one out this is my only option. The value is ultimately stored in a VB Long variable (well, its an array of data), but it seems this algorithm just works with this bug(?) and I don't know how to convert that to C++.
    The human brain cannot hold all of the knowledge that exists in this world, but it can hold pointers to that knowledge.

  4. #4
    G&G Moderator chemicalNova's Avatar
    Join Date
    Jun 2002
    Location
    Victoria, Australia
    Posts
    4,246
    I swear I saw a few examples of JPEG compression at Planet Source Code. They use DIBBits and the like and Byte arrays.

    Phreak

    Visual Studio 6, Visual Studio.NET 2005, MASM

  5. #5
    The picture isn't missing BuggyProgrammer's Avatar
    Join Date
    Oct 2000
    Location
    Vancouver, Canada
    Posts
    5,217
    I have seen the Jpeg thing in pure VB code as well on PSC.

    Perhaps it is doing rounding where if the most sigfig is odd and the most sigfig after the decimal is 5, it will round up. IE:

    1.5->2
    2.5->2
    3.5->4
    4.5->4

    (I did say maybe, but I'm pretty sure.)

    It's called banker's rounding by the way: http://blogs.msdn.com/ericlippert/ar.../26/53107.aspx
    Remember, if someone's post was not helpful, you can always rate their post negatively .

  6. #6
    Former Admin/Moderator MartinLiss's Avatar
    Join Date
    Sep 1999
    Location
    San Jose, CA
    Posts
    33,431

    Re: divide bug?

    Originally posted by DNA7433
    How come CInt(750 / 100) = CInt(850 / 100)?

    They both equal 8...how is that possible? and how would i emulate this weird formula evaluation in C++?

    I'm trying to convert some VB code (that works perfectly) to C++ and this is a bug I tracked down. C++ evaluates static_cast<long>(750 / 100) = 7, static_cast<long>(850 / 100) = 8
    What you are seeing is actually a result of the VB's use of what is called Banker's rounding. The results of those divisions are of course 7.5 and 8.5 respectivly, but since you are asking VB to convert them to Integers they have to be rounded. Here is VB's explanation of Banker's Rounding

    When you add rounded values together, always rounding .5 in the same direction results in a bias that grows with the more numbers you add together. One way to minimize the bias is with banker's rounding.

    Banker's rounding rounds .5 up sometimes and down sometimes. The convention is to round to the nearest even number, so that both 1.5 and 2.5 round to 2, and 3.5 and 4.5 both round to 4. Banker's rounding is symmetric.

    In Visual Basic for Applications, the following numeric functions perform banker's rounding: CByte(), CInt(), CLng(), CCur(), and Round().

  7. #7

    Thread Starter
    Fanatic Member
    Join Date
    May 2001
    Posts
    837
    Thanks everybody. I wrote some code to mimic the Bankers rounding and it doesn't crash anymore. The JPEG comes out as a big gray square (not the image i was compressing). I looked at the files in binary and it seems half the data isn't being written. More debugging!
    The human brain cannot hold all of the knowledge that exists in this world, but it can hold pointers to that knowledge.

  8. #8
    The picture isn't missing BuggyProgrammer's Avatar
    Join Date
    Oct 2000
    Location
    Vancouver, Canada
    Posts
    5,217
    Why don't you just use the intel jpeg library? Although you don't directly set the bytes and return a byte array, you can set the bytes to a dib (which the jpeg dll uses) and get the bytes again after.
    Remember, if someone's post was not helpful, you can always rate their post negatively .

  9. #9

    Thread Starter
    Fanatic Member
    Join Date
    May 2001
    Posts
    837
    I was using that, and if I remember the only thing you could do was save the compressed bytes to a file. I don't want to save them to a file, I want them back.
    The human brain cannot hold all of the knowledge that exists in this world, but it can hold pointers to that knowledge.

  10. #10
    MS SQL Powerposter szlamany's Avatar
    Join Date
    Mar 2004
    Location
    Connecticut
    Posts
    18,263
    Look at this simple example:

    VB Code:
    1. Private Sub Form_Load()
    2.  
    3. Dim x1 As Long
    4. Dim x2 As Long
    5. Dim x3 As Long
    6. Dim x4 As Long
    7.  
    8. Dim r1 As Long
    9. Dim r2 As Long
    10.  
    11. x1 = 750
    12. x2 = 100
    13. x3 = 850
    14. x4 = 100
    15.  
    16. Debug.Print x1 / x2
    17. Debug.Print x3 / x4
    18.  
    19. r1 = x1 / x2
    20. r2 = x3 / x4
    21.  
    22. Debug.Print "Now for r1 and r2"
    23. Debug.Print r1, r2
    24.  
    25.  
    26. End Sub

    It returns:

    7.5
    8.5
    Now for r1 and r2
    8 8

    This illustrates the evils of coercion (I just did a post on this two days ago). Debug.Print is treating the "expression" x1/x2 as a variant - and furthermore as a float. Even though both operands are interger type (long).

    But if I stick the results in a LONG, they both end up being 8 - makes debugging in a language so loose in coercion a pain-in-the...

    BTW - if you are working with colors, never, ever use DOUBLE - these are INTEGERS - LONG and need to be treated as such throughout your code. As soon as you loose control of the datatype, it's over

    Don't know if this will help, but try PUBLIC CONST... for all your "literal" values - maybe that will help VB focus on a particular datatype

Posting Permissions

  • You may not post new threads
  • You may not post replies
  • You may not post attachments
  • You may not edit your posts
  •  



Click Here to Expand Forum to Full Width