• oh boy (unregistered)

    pr8?

  • DZ-Jay (cs) in reply to oh boy
    Anonymous:
    pr8?


    p-rate... price rate??

        dZ.
  • El Duderino (cs)

    pr8?  WTF is pr8?

  • El Duderino (cs) in reply to El Duderino

    I guess we all wondered the same thing . . .[:'(]

  • Imperfect (unregistered)

    Notwithstanding the fact that ANY global variables are badbadbad, isn't "intFractions" an undocumented global variable?

    Just... wow.

  • David (unregistered) in reply to Imperfect
    Anonymous:

    Notwithstanding the fact that ANY global variables are badbadbad, isn't "intFractions" an undocumented global variable?

    Just... wow.

     

    Really?  How do you do frequently used constants then?  Do you declare them in every method you need them in or do you pass them to every method that needs them as a parameter?  Neither is preferable to maintaining a list of constants at the top of a header file or the body of your program. 

  • TheDan666 (cs)

    "Notwithstanding the fact that ANY global variables are badbadbad, isn't "intFractions" an undocumented global variable?"

    What about the total incongriguity of a variable named intFractions ?

  • evolved (unregistered)

    Alex I love the daily wtf, but the vb6 wtf's are just plain old cliche at this point.

    This wasn't really that LOL'able IMHO.

     

    .j

  • Mordac (unregistered) in reply to David

    Global variables are bad. Global constants arent.

  • Anonymous the 3rd (unregistered) in reply to David
    Anonymous:
    Anonymous:

    ... ANY global variables are badbadbad ...

    Really?  How do you do frequently used constants then?

    To quibble on a technicality, frequently used constants aren't really variable, are they?  I mean, they may be variables, but they don't change.  That's what makes it (more) permissible to define constants globally.

  • . (unregistered)

    There's nothing wrong with parameters that often don't change from one call to the next being replaced with global variables, it makes it faster because they don't need to get pushed onto the stack every time you call the function.

  • Maurits (cs) in reply to .
    Anonymous:
    There's nothing wrong with parameters that often don't change from one call to the next being replaced with global variables, it makes it faster because they don't need to get pushed onto the stack every time you call the function.


    But if you have lots of them, and you never call the associated functions, that's just a waste of space.

    Also they lead to hard-to-track bugs involving functions calling each other, and using the same global variable.
  • bz922x (cs)
    Public Function Round_price(curr_price As Double) As Double
    ...
    Round_price = CDbl(curr_price)


    I like the safe coding practice.  Always coerce the value to the output type. Especially when it is already in the output type!

    But really, VB6's rounding functions really suck, so every VB system has re-implemented Round to add need features. This one is just a particularly hideous, misguided, non-math based, re-implementation.
  • Fregas (unregistered)

    Global variables!  GAaaaack!!!!

  • cm5400 (cs)

    WOW,  this developer needs a swirly...[:P]  Maybe it will clean all the gunk out of his head.[:D]

  • John Smallberries (cs) in reply to Maurits
    Maurits:
    Anonymous:
    There's nothing wrong with parameters that often don't change from one call to the next being replaced with global variables, it makes it faster because they don't need to get pushed onto the stack every time you call the function.


    But if you have lots of them, and you never call the associated functions, that's just a waste of space.

    Also they lead to hard-to-track bugs involving functions calling each other, and using the same global variable.

    And if one function inadvertantly changes the global....
  • David (unregistered) in reply to Anonymous the 3rd
    Anonymous:
    Anonymous:
    Anonymous:

    ... ANY global variables are badbadbad ...

    Really?  How do you do frequently used constants then?

    To quibble on a technicality, frequently used constants aren't really variable, are they?  I mean, they may be variables, but they don't change.  That's what makes it (more) permissible to define constants globally.

    Sure they are variable.  I run the program once.  I go back, change the value, and run it again.  It just changed.  The fact that they can change at all is the entire reason for using constant variables in the first place rather than just comparing variables to literals.  Regardless I don't see the point of arguing semantics as no one was in the first place.  Maybe the guy I originally replied to wasn't thinking of constants or didn't mean them when he said global variables, but I cringe whenever I see blanket statements like that. 

  • Anonymous (unregistered)

    That intFractions part is pretty funky. From what I can tell, it converts numbers like 12.34 to 12 + (34 / intFractions). Why anyone would ever want to store fractions in a floating point value like that I have no idea... and why the weird special treatment for intFractions=32?

  • Russ (unregistered) in reply to David
    Anonymous:
    Anonymous:
    Anonymous:
    Anonymous:

    ... ANY global variables are badbadbad ...

    Really?  How do you do frequently used constants then?

    To quibble on a technicality, frequently used constants aren't really variable, are they?  I mean, they may be variables, but they don't change.  That's what makes it (more) permissible to define constants globally.

    Sure they are variable.  I run the program once.  I go back, change the value, and run it again.  It just changed.  The fact that they can change at all is the entire reason for using constant variables in the first place rather than just comparing variables to literals.  Regardless I don't see the point of arguing semantics as no one was in the first place.  Maybe the guy I originally replied to wasn't thinking of constants or didn't mean them when he said global variables, but I cringe whenever I see blanket statements like that. 



    You are kidding, right? I hardly think modifying source code and recompiling means that a constant isn't a constant. And the main reason for using constants is that sprinkling numbers all over your code obfuscates meaning and reduces readability. Or, if you're using strings, reducing the opportunities for inconsistent spelling and typos. Being able to change a value in one place is an important, but definitely secondary, benefit.

  • Nick (unregistered) in reply to David

    variables != constants. use a global constant for constants ...

  • Nick (unregistered) in reply to David
    Anonymous:
    Anonymous:
    Anonymous:
    Anonymous:

    ... ANY global variables are badbadbad ...

    Really?  How do you do frequently used constants then?

    To quibble on a technicality, frequently used constants aren't really variable, are they?  I mean, they may be variables, but they don't change.  That's what makes it (more) permissible to define constants globally.

    Sure they are variable.  I run the program once.  I go back, change the value, and run it again.  It just changed.  The fact that they can change at all is the entire reason for using constant variables in the first place rather than just comparing variables to literals.  Regardless I don't see the point of arguing semantics as no one was in the first place.  Maybe the guy I originally replied to wasn't thinking of constants or didn't mean them when he said global variables, but I cringe whenever I see blanket statements like that. 



    Um, that's the definition of a constant--something that's not going to change *during the run of a program*, as opposed to a variable that ...well, can.

  • silverpie (cs) in reply to Anonymous

    The "prices" we're seeing here are stock prices. Apparently, it uses a system where a price in the old-style notation of 32 5/8 would be passed as 32.5 (with intFractions set to 8 in that circumstance, and this function would convert it to the decimal price of 35.625. The denominator of 32 is used for bond quotes, and the special-case code avoids problems with a numerator of 10 or 20 (which would lose a digit in the CStr command). It makes sense for data entry to be in that form: if you have a lot of those numbers to enter, it's quicker; on the other hand, it should immediately be converted to a proper float directly from the entered string.

    (Another example of using a float, at least in its string form, in that way is in baseball stats, where .1 and .2 represent one-third and two-thirds of an inning; similarly the cricket usage of overs.balls, with a base of 6.)

    But rather than make a string (and there's another foul there--with the CStr function, you are not guaranteed that the decimal separator will be a period, so this code breaks on a lot of international settings), why not just extract the fractional part with curr_price-int(curr_price) and do math on that?

  • dubwai (cs) in reply to .

    Anonymous:
    There's nothing wrong with parameters that often don't change from one call to the next being replaced with global variables, it makes it faster because they don't need to get pushed onto the stack every time you call the function.

    That's the worst reason to use global variables that I've ever seen.  What's the return on that, you think?

    I don't know where you've been but global variables have been the bane of software development for a quite a while.  If you feel that you are smarter than everyone else then go right ahead and have fun when the bugs start rolling in.

  • Notshakespeare (unregistered) in reply to .

    There's nothing wrong with parameters that often don't change from one call to the next being replaced with global variables, it makes it faster because they don't need to get pushed onto the stack every time you call the function.

    Doesn't sound very thread-safe to me...

  • loneprogrammer (cs) in reply to dubwai
    dubwai:

    Anonymous:
    There's nothing wrong with parameters that often don't change from one call to the next being replaced with global variables, it makes it faster because they don't need to get pushed onto the stack every time you call the function.

    That's the worst reason to use global variables that I've ever seen.  What's the return on that, you think?


    It depends on how many times that function gets called.  If the amount is 300 million times, it might be quite a lot of time saved.  If the amount is less than a few thousand times, then it might be so little time that nobody will notice.

    Anyway, everybody knows global variables are bad, but Singleton classes are just super awesome great!
  • JamesCurran (cs) in reply to dubwai
    dubwai:

    That's the worst reason to use global variables that I've ever seen.  What's the return on that, you think?

    I don't know where you've been but global variables have been the bane of software development for a quite a while. 

    Not necesarily.  If this is the case as silverpie describes, then intFraction seems to be something that wants to be set once at the start of the program, and used by all calls throughout the run of the program.  If the term "global variable" bothers you, call it a "configuration setting".

     

  • dubwai (cs) in reply to loneprogrammer
    loneprogrammer:
    dubwai:

    Anonymous:
    There's nothing wrong with parameters that often don't change from one call to the next being replaced with global variables, it makes it faster because they don't need to get pushed onto the stack every time you call the function.

    That's the worst reason to use global variables that I've ever seen.  What's the return on that, you think?


    It depends on how many times that function gets called.  If the amount is 300 million times, it might be quite a lot of time saved.  If the amount is less than a few thousand times, then it might be so little time that nobody will notice.

    Anyway, everybody knows global variables are bad, but Singleton classes are just super awesome great!

    I'm asking what's the return on a single call.  We can easily multiply that.

    When I've done tests on stuff like this on my laptop, I ususally see results on the order of nano-seconds.  i.e. you have to run 1 million times just to see a change on the millisecond scale.  THe other thing you've left out is 300 million times over what time frame?  1 year, one second?  It makes a big difference especially since most applications are idle for a large portion of their run-times.

  • dubwai (cs) in reply to JamesCurran
    JamesCurran:
    dubwai:

    That's the worst reason to use global variables that I've ever seen.  What's the return on that, you think?

    I don't know where you've been but global variables have been the bane of software development for a quite a while. 

    Not necesarily.  If this is the case as silverpie describes, then intFraction seems to be something that wants to be set once at the start of the program, and used by all calls throughout the run of the program.  If the term "global variable" bothers you, call it a "configuration setting".

    I was responding to a post that claimed that using globals to avoid putting variables on the stack was a good approach.  Ignoring that there are other ways to not use the stack without globals, that is a really bad case of premature optimization / micro-optimization.

  • Rank Amateur (cs) in reply to Anonymous

    Anonymous:
    That intFractions part is pretty funky. From what I can tell, it converts numbers like 12.34 to 12 + (34 / intFractions). Why anyone would ever want to store fractions in a floating point value like that I have no idea... and why the weird special treatment for intFractions=32?

    Thanks for asking first, because my pathetic humanoid brain sure couldn't figure it out. I expected it to round to the nearest fraction (e.g., 0.25, 0.50, 0.75, 0.00 for intFractions = 4). But no. Then I though maybe it was supposed to get the numerator of a given denominator (intFractions), maybe to represent NYSE prices in some weird way. Uh-uh.

    intFractions = 4

    round_to_digits = 2

    Round_price(3.719) -> 182.75

    WTF kind of price rounding is that?

    --RA

  • jeremydwill (cs) in reply to JamesCurran
    JamesCurran:
    dubwai:

    That's the worst reason to use global variables that I've ever seen.  What's the return on that, you think?

    I don't know where you've been but global variables have been the bane of software development for a quite a while. 

    Not necesarily.  If this is the case as silverpie describes, then intFraction seems to be something that wants to be set once at the start of the program, and used by all calls throughout the run of the program.  If the term "global variable" bothers you, call it a "configuration setting".

     

    That is just fine, but then the safer thing to do is place the "configuration setting" behind a method (function) that does not permit changing the value after it has been set initially. A global variable means that the value can be modified from any routine in the app, which is highly undesirable. The principle is called encapsulation (or information hiding for all you Steve McConnell fans).

    Since this is VB6 we are discussing, all that would need to be done is to create a function in a module that returns the configuration setting (or it could be a read-only property, although most people do not seem to know that you can have properties in modules in VB6). Yes, there would be overhead to this call versus directly accessing a variable, but I would favor safety over speed. As one of my favorite authors (Joe Celko) says "I can get great performance if i do not have to get the right answer".

  • Russ (unregistered) in reply to loneprogrammer
    loneprogrammer:
    dubwai:

    That's the worst reason to use global variables that I've ever seen.  What's the return on that, you think?


    It depends on how many times that function gets called.  If the amount is 300 million times, it might be quite a lot of time saved.  If the amount is less than a few thousand times, then it might be so little time that nobody will notice.

    Anyway, everybody knows global variables are bad, but Singleton classes are just super awesome great!


    The function would have to be called a lot. I just whipped up a couple of trivial C programs that call a function 300 million times, the only difference being one of them passes a couple of long ints and the other one uses globals. Compiled with no optimisation, the speed difference is about 0.3 seconds. Compiled with the -O3 flag, that comes down to about 3/1000ths, on average (over about 10 executions of each app). I'm hard pressed to think of any situation, even in realtime or embedded application spaces, where a speed penalty of 3/1000ths of a second over 300 million distinct function calls is going to make a difference.
  • Rank Amateur (cs) in reply to Rank Amateur
    Rank Amateur:

    Anonymous:
    That intFractions part is pretty funky. From what I can tell, it converts numbers like 12.34 to 12 + (34 / intFractions). Why anyone would ever want to store fractions in a floating point value like that I have no idea... and why the weird special treatment for intFractions=32?

    Thanks for asking first, because my pathetic humanoid brain sure couldn't figure it out. I expected it to round to the nearest fraction (e.g., 0.25, 0.50, 0.75, 0.00 for intFractions = 4). But no. Then I though maybe it was supposed to get the numerator of a given denominator (intFractions), maybe to represent NYSE prices in some weird way. Uh-uh.

    intFractions = 4

    round_to_digits = 2

    Round_price(3.719) -> 182.75

    WTF kind of price rounding is that?

    --RA

    Wait! I just figured it out! It's for pricing airline tickets.

    No, seriously, it's when curr_price's decimal digits represent the numerator of a given denominator stored in intFractions. It only works when curr_price goes out to <= 2 decimal places (after being Cstr-ed), and intFractions is <= 32. For example, if intFractions is 16, Round_price will convert a curr_price of 3.12 to its true value of 3.75 (with round_to_digits >= 2). That's why inFractions is global --there must be a function somewhere that converts 3.75 to 3.12 for intFractions of 16 (or 3.06 for intFractions of 8... or 3.6, either would work), and this way you can be sure <cough, cough> that both use the same intFractions.

    But... why?

    --RA

  • El Duderino (cs) in reply to Rank Amateur

    So I fiddled with the code and in addition to the purposeless use of global variables it's terribly overloaded.  If you set intFractions to 0 it performs simple rounding.  However, for stock prices the source data might store 12.5 where intFractions = 8 to represent 12 5/8.  The second half of the function deals with that transformation -- that's all kosher assuming that they have no control over the format of the source data (WTFs breed more WTFs.)

    However, the function shouldn't have attempted to perform both of these requirements.  One function rounds and another handles fractional data -- please don't spaghetti it all together.

    I also have a theory behind pr8:  pr1 through pr7 were all previously defined as global variables. [:'(]

     

     

  • boohiss (unregistered)

    I know your CS professors always say "RAWR GLOBAL VARIABLES BAAAAD", but don't automatically dismiss the usefullness of global variables in certain situations.

    This awful rounding function isn't one of those situations, but I'm just saying.

  • Mike Weller (unregistered) in reply to boohiss

    For some reason IE7 beta1 has flagged this as a potential phishing site :P

    Don't worry though, it did the same with xbox.com. I submitted a form saying it isn't suspiscious.

  • WTFer (cs) in reply to Mike Weller
    Anonymous:
    For some reason IE7 beta1 has flagged this as a potential phishing site :P

    Don't worry though, it did the same with xbox.com. I submitted a form saying it isn't suspiscious.


    Hi, Ebay customer. For security reason we are asking all our users to send us their password and email address to the following address ebay@ebay-scammer.com. That way we can verify your account is currently active.

    Thanks,
    Ebay Staff

    /I'm so not helping

  • phelyan (cs)

    Sorry, I started crying when he started with the decimal point in the string...

    "Constants aren't. Variables don't."

  • Andrei (unregistered)
    <!--StartFragment --> 
    Anonymous:
    I know your CS professors always say "RAWR GLOBAL VARIABLES BAAAAD", but don't automatically dismiss the usefullness of global variables in certain situations. This awful rounding function isn't one of those situations, but I'm just saying.


    I actually find great use in having a static global class for multithreaded applications.

    Basically, having a program ID, a vector of separate threads comes in handy - that's how I got my server to work. Also, when having a GUI app in java, which can be dozens of levels deep (Below is an example), having global variables can easily tie a controller. Separate the gui and the driver code.

    And an example of gui?
    The application is a panel, which has multiple faces, each face having different panels grouping the data logically, and each panel has a layout that logically separates the component, each of which has multiple buttons and drivers.

    Having a central driver makes all of that simply "globalData.client.lobby.tableList.tables[0].seat[0].user = new user"

    And yes, I actually have code like that.
  • Maestro (unregistered) in reply to Andrei

    CLng from mircrosoft is rubbish... It rounds to the nearest even number when the decimal component equals 0.5.  The Round function mentioned in this WTF is not available in all VB development environments so writing your own needs to be done.  This function has been taken out of context to the environment in which it was developed.

    The rounding I use (when neccessary) is as follows (assuming two decimal places):

    newvalue = fix(oldvalue*100+0.5)/100

    Fix truncates towards 0 and Int (as used in this WTF) rounds towards a smaller value, which is not good for negative values.

  • Gary and the Samoyeds (unregistered) in reply to Maestro

    Well, in scientic, mathematical, and statistical work, that is precisely what you want.  If you always round 0.5000... up (or down), that introduces a slight bias.

    I will admit I don't know what the standard is in financial calculations.  Is round-to-even wrong?  Do you always round 0.5 -> 1.0?

  • whojoedaddy (cs)

    I wonder if a few people worked on this. Some of the variables are in Hungarian Notation ... some aren't .... oh well who needs consistency.

  • Foon (cs)

    The real problem here is storing currency in floating-point variables. Currency should be stored as an integral number of the lowest unit - cents. Do that, and rounding becomes a non-issue.

  • phelyan (cs) in reply to Foon

    Foon:
    The real problem here is storing currency in floating-point variables. Currency should be stored as an integral number of the lowest unit - cents. Do that, and rounding becomes a non-issue.

    Don't get me started on money values and rounding. Another problem is that often a lack of separation of presentation and business layers forces some stupidities:

    Standard VAT (17.5%) of 1,515: 265.125
    What the user wants to see: 265.13
    13 lots of above: 3,446.625 (displayed as 3,446.63)
    13 lots if taken from displayed value: 3,446.69

    Suddenly you're sixpence out because somewhere the rounded value has been written back into the database. Rounding needs to be done at sane places. And, yes, depending on where and how, either of those values could be considered 'correct'.

  • Drak (cs) in reply to TheDan666
    TheDan666:

    "Notwithstanding the fact that ANY global variables are badbadbad, isn't "intFractions" an undocumented global variable?"

    What about the total incongriguity of a variable named intFractions ?

     

    Maybe it's an undocumented global constant, and that's why it is named different from all those variables?

    Drak

  • rob (unregistered) in reply to Drak

    Doesn't .Net do banker's rounding, by default? Wouldn't you have to re-implement round do get it to do standard arithmetic round?

  • Raw (unregistered) in reply to rob

    There are legitimate reasons for writing your own round function. There are no legitimate reasons to do it in this effed up way, but there are reasons to do it.

    Example: The VB library function is not internationalized. Different countries have different rules. In fact, depending on when you went to school here in Sweden, you may have learned to handle a 5 as either round up, round down or round to nearest even.

    There are good reasons for all these variants and which is used is just a convention. Since VB does not do it all these ways, you have to do it.

  • phelyan (cs) in reply to Raw

    Swiss round to the nearest 5 centimes. Nightmare that was to implement everywhere in the system...

  • foxyshadis (cs) in reply to rob
    Anonymous:
    Doesn't .Net do banker's rounding, by default? Wouldn't you have to re-implement round do get it to do standard arithmetic round?

    By default, but it has a flag to switch to standard rounding. I think it even includes nightmare ones like the swiss in an i18n package, but don't quote me.
  • Justin. (unregistered) in reply to phelyan
    phelyan:
    Swiss round to the nearest 5 centimes. Nightmare that was to implement everywhere in the system...


    Well it shouldn't be!  Just work out the granularity you are dealing with, convert to it, round, convert back to display values.

    Tsch.  Kids today.

    Justin.
    Database Designer and Java Guru
  • phelyan (cs) in reply to Justin.

    Anonymous:
    phelyan:
    Swiss round to the nearest 5 centimes. Nightmare that was to implement everywhere in the system...


    Well it shouldn't be!  Just work out the granularity you are dealing with, convert to it, round, convert back to display values.

    Tsch.  Kids today.

    Justin.
    Database Designer and Java Guru

    Gee, we have to display our self-given titles under the name to instill a sense of importance now?

    It becomes a nightmare when you have to do it in 20 different places throughout an organically grown system because every other class uses its own rounding methods.

    Phelyan.
    Jack Of Some Trades and Not Full Of Self

Leave a comment on “Reinventing The Round”

Log In or post as a guest

Replying to comment #:

« Return to Article