• (cs) in reply to Ken B.
    Ken B.:
    Bill&Ted:
    Not necessarily changed - the value of Math.PI [1] is never going to change, but it's still sensible to make it a constant so that (1) developers don't have to remember the value; and (2) they can't screw up by making a typo (OK, other than making it Math.PHI or something..).

    [1] unless someone got it wrong originally...

    Well, the value of Math.PI might change. Consider moving to a platform more a different floating-point precision. (Or does Java require a certain precision, regardless of platform?)

    Or, maybe you're running your program in Indiana.

    Aaah, you kids and your crazy classes! When I was your age, anybody who'd ever touched BASIC (and none of that "Visual" foolishness, I mean real BASIC) knew instinctively that the value of pi was 4*ATN(1), good to whatever precision you stored it in.

  • (cs)
    While not nearly as bad as Magic Numbers, Magic Constants certainly aren't elegant

    I totally disagree. There is very little at best advantage of using a constant like NUMBER_FOUR instead of just 4. Numbers and constants like these should always be avoided and the constant should say something like NUMBER_OF_CARDS_IN_HAND.

  • Finch (unregistered) in reply to Nik
    Nik:
    J. Madden:
    Matt Westwood:
    I sincerely hope your use of "literally" is literally incorrect.

    Seems fine to me.

    nice, I can't tell if you're joking

    Suggested reading: http://xkcd.com/725/ :-)

  • Andrew (unregistered) in reply to RBoy
    RBoy:
    Bert Glanstron isn't very funny

    Good thing we have an authoritative opinion on that now. Now I realize my spontaneous chuckling every time I read a Bert Glanstron retread is due to something other than its funniness.

  • riton (unregistered) in reply to thenextguy

    I think you are doint it wrong. What if the array you are allocating changes from int to double in the future ? there is a risk you forget to change the 4. Prefer using sizeof(your_variable) instead of the numbers. Just a suggestion..

  • iToad (unregistered) in reply to COHERENCE_NOT_FOUND
    COHERENCE_NOT_FOUND:
    public static final float FLOAT_NOT_QUITE_PI = (LONG_VALUE_TEN + LENGTH_TWELVE) / (NINE_STRING + (COMPARE_RESULT_NEGATIVE * (PLUS_ONE + BIGDECIMAL_ONE) ));

    mmmmmm... FLOAT_NOT_QUITE_PI..

    Not bad... It's almost COBOL.
  • Peter (unregistered) in reply to Andrew
    Andrew:
    RBoy:
    Bert Glanstron isn't very funny
    Good thing we have an authoritative opinion on that now. Now I realize my spontaneous chuckling every time I read a Bert Glanstron retread is due to something other than its funniness.
    Yes, that's true.
  • Abby Normal (unregistered)

    public static final String PAULA_BEAN = "Brilliant";

  • (cs)

    Wow.

  • Joey Alcorn (unregistered)

    Say... This would be handy when I localize to countries where 1 = 2...

  • Sutherlands (unregistered) in reply to Abby Normal
    Abby Normal:
    public static final String PAULA_BEAN = "Brilliant";
    You can't even get the joke right.
  • (cs) in reply to dtech
    dtech:
    While not nearly as bad as Magic Numbers, Magic Constants certainly aren't elegant

    I totally disagree. There is very little at best advantage of using a constant like NUMBER_FOUR instead of just 4. Numbers and constants like these should always be avoided and the constant should say something like NUMBER_OF_CARDS_IN_HAND.

    You need a better sarcasm detector dude. There is not a single non-sarcastic sentence in the entire article.

  • (cs)

    See, what they should have done is this:

    public enum wtf {
         FOUR(4),THREE(3),INTEGER_FOUR(4)...
    }
  • (cs) in reply to fahadsadah
    fahadsadah:
    This is not a WTF.

    On embedded systems with no filesystem...

    Since you resurrected this meme...

    I have found a practical use for defining constants for much-used integer values such as 0 and 1 in embedded systems. In a system with 32 kbytes of ROM space I simply could not afford to allow the C compiler to litter it with numerous 32-bit zeroes and ones. Declaring

    const int ZERO = 0;
    const int ONE = 1;
    

    and using them everywhere I could saved me about 2 kbytes of ROM.

    OTOH, I doubt today's CodeSOD has any such practical purpose.

  • Jesus (unregistered) in reply to Peter
    Peter:
    Andrew:
    I realize my spontaneous chuckling every time I read a Bert Glanstron retread is due to something other than its funniness.
    Yes, that's true.

    Peter, Andrew, James, and John, Come and follow me!

  • NitPicker (unregistered) in reply to thenextguy

    Remove the comment and use:

    malloc( 4 * sizeof(int) + sizeof(char) )

    Now the expression and comment do not need to be maintained in step if anything needs to change. A comment if added should explain why you need 4 ints and a char worth of storage, else it only gets in the way.

  • EngleBart (unregistered) in reply to Someone You Know
    Someone You Know:
    Allen's colleague:
    public static final int COMPARE_RESULT_ZERO = 0 ; public static final int COMPARE_RESULT_ONE = 1 ; public static final int COMPARE_RESULT_NEGATIVE = -1 ;

    It seems likely these are being used somewhere in conjunction with a Comparable or Comparator. If that's the case there's another WTF here in assuming that compareTo() methods will return -1 for "less than" and +1 for "greater than". The only assumption you're allowed to make is that it returns a negative value for "less than" and a positive value for "greater than".

    I suspect that these were used for return values from implementers of Comparable. Better names in that case would be

    public static final int COMPARE_RESULT_EQUAL = 0 ; public static final int COMPARE_RESULT_GREATER = 1 ; public static final int COMPARE_RESULT_LESSER = -1 ;

    If you are going to create a constant, use the real meaning!

    In agreement with other posters that this still does not help in dealing with the results a Comparable method. Even if it was your own object, it would be a bad idea to assume these are the only possible return values. -2 means less than just like -1. Maybe some helper methods?

    class CompareUtil { static boolean isLessThan(int compareToReturnValue) { return compareToReturnValue < 0; } }

    if (CompareUtil.isLessThan(a.compareTo(b))) ... same as if (a.compareTo(b) < 0)

    I don't see any real readability benefit...

    Hopefully the compiler will inline everything for you!

  • Brent (unregistered) in reply to The Nerve
    The Nerve:
    I think that most people already get this, but if they did, then this wouldn't keep cropping up so often.

    Ok:

    x = x1 + vt - 4.9 * t * t;

    Slower, but more readable:

    x = x1 + vt + .5 * -9.8 * t * t;

    Any reasonable compiler should produce the same output for either case... it would only be slower during compilation, so you should always feel free to go with what you feel is cleaner when doing arithmetic with consts.

    In case I forgot what 9.8 is or can't figure it out based on context:
    x = x1 + vt + .5 * Constants.ACCELERATION_OF_GRAVITY * t * t;
    or
    x = x1 + vt + Constants.ONE_HALF_OF_GRAVITY * t * t;

    Which should also include these if the compiler is any good.

  • ÃÆâ€â„ (unregistered)

    Magic constants aren't that bad. Physicists use them all the time (Graviational constant, speed of light, etc).

  • The Nerve (unregistered) in reply to ÃÆâ€â„
    ÃÆâ€â„:
    Magic constants aren't that bad. Physicists use them all the time (Graviational constant, speed of light, etc).

    Oh, now I see what happened here. The guy who wrote the constants class was not writing the constants to be used. He was simply (as a scientist) documenting what the constants were. So, in his inspection of the code and the Java Language Specification, he discovered that FOUR was indeed 4, and that INTEGER_FOUR is actually 4.

    Good job! And thanks for showing us why this isn't a WTF!!!

  • Jay (unregistered) in reply to Kelderek
    Kelderek:
    Good to see that INTEGER_ONE and INTEGER_FIVE are defined twice. (Just in case)

    Sure. That way if one of the places that needs a constant 5 is changed to need, say, a 6, we can just redefine one of the INTEGER_FIVE's to INTEGER_FIVE=6, while leaving the other unchanged, so we don't break the other code.

  • ÃÆâ€â„ (unregistered) in reply to The Nerve
    The Nerve:
    ÃÆâ€â„:
    Magic constants aren't that bad. Physicists use them all the time (Graviational constant, speed of light, etc).

    Oh, now I see what happened here. The guy who wrote the constants class was not writing the constants to be used. He was simply (as a scientist) documenting what the constants were. So, in his inspection of the code and the Java Language Specification, he discovered that FOUR was indeed 4, and that INTEGER_FOUR is actually 4.

    Good job! And thanks for showing us why this isn't a WTF!!!

    Human sees:

    Mother Nature:
    GRAVITATION_CONSTANT = 6.67428E-11 // N(m/kg)^2

    God wrote:

    God:
    float gravitation = isHumanLooking() ? 6.67428E-11 : PROFIT
  • North Shore Beach Bum (unregistered) in reply to Ken B.
    Ken B.:
    Well, the value of Math.PI might change. Consider moving to a platform more a different floating-point precision. (Or does Java require a certain precision, regardless of platform?)

    Or, maybe you're running your program in Indiana.

    Java has set precision for all its types across all platforms. That way the source doesn't need to be compiled to byte code for each platform.

  • Jay (unregistered) in reply to Kempeth
    Kempeth:
    powerlord:
    Note to spoil your joke or anything... but Java already has a double not quite pi constant: java.lang.Math.PI

    Really? I always thought that those constants where EXACTLY equal to pi...

    I recall when I was a kid, my math teacher explaining that pi cannot be exactly expressed by any fraction or finite-length string of decimals. He conluded by saying, "The only way to express the value of pi exactly is to say 'pi'."

    Which is not quite true -- you could give an algorithm for calculating it -- but you get the idea.

  • (cs) in reply to iToad
    iToad:
    COHERENCE_NOT_FOUND:
    public static final float FLOAT_NOT_QUITE_PI = (LONG_VALUE_TEN + LENGTH_TWELVE) / (NINE_STRING + (COMPARE_RESULT_NEGATIVE * (PLUS_ONE + BIGDECIMAL_ONE) ));

    mmmmmm... FLOAT_NOT_QUITE_PI..

    Not bad... It's almost COBOL.

    now it is.

    A100-GET-SOME-PIE.
         COMPUTE FLOAT-NOT-QUITE-PI = 
                (LONG-VALUE-TEN + LENGTH-TWELVE) / 
                (NINE-STRING + (COMPARE-RESULT-NEGATIVE * 
                (PLUS-ONE + BIGDECIMAL-ONE)))
         .
        
    

    The most important apps in most companies are written in COBOL (mainly your payroll app).

  • Jay (unregistered) in reply to Steve The Cynic
    Steve The Cynic:
    NoAstronomer:
    If only more languages had the ability to change constants on the fly. It's the way of the future.
    No, it's the way of the past. Fortran had this ability forty years ago:
        SUBROUTINE FRED(A,B)
        A = B
        END
    ...
        CALL FRED(7,4)
        WRITE(5,*) 7

    output of this program on machines that support this:

    4

    WTF?!?

    (On other machines, e.g. Sun's Solaris Fortran, it crashes when writing to A in FRED() because the 7 is stored in a read-only section. It is still passed by reference, though.)

    Yes, I have fond memories of tracking down a bug caused by exactly this in a Fortran program 20-some years ago. Somebody inadvertantly redefined the constant "1" to be "2". Of course the problem didn't show up until many lines later in the code. And so I was doing dumps going, "Okay, so now X=3, we add 1 to it ... and how did it end up being 5? I must have missed another update ..."

  • Big Excel Sheet (unregistered) in reply to Nome de Plume

    Using,

    malloc(4 * sizeof(int) + sizeof(void *));

    might indicate a NULL terminator, whereas,

    malloc(4 * sizeof(int) + 1);

    is more likely to indicate a nul terminator.

  • Brent (unregistered) in reply to Jay
    Jay:

    I recall when I was a kid, my math teacher explaining that pi cannot be exactly expressed by any fraction or finite-length string of decimals. He conluded by saying, "The only way to express the value of pi exactly is to say 'pi'."

    Which is not quite true -- you could give an algorithm for calculating it -- but you get the idea.

    This is why you need to use constants line ONE, TWO, etc. You never known when someone is going to redefine the integers to be multiples of arctan(1), just so that they can set PI equal to 4 and be exactly correct.

  • Larry (unregistered) in reply to Jay
    Jay:
    Steve The Cynic:
    NoAstronomer:
    If only more languages had the ability to change constants on the fly. It's the way of the future.
    No, it's the way of the past. Fortran had this ability forty years ago:
        SUBROUTINE FRED(A,B)
        A = B
        END
    ...
        CALL FRED(7,4)
        WRITE(5,*) 7

    output of this program on machines that support this:

    4

    WTF?!?

    (On other machines, e.g. Sun's Solaris Fortran, it crashes when writing to A in FRED() because the 7 is stored in a read-only section. It is still passed by reference, though.)

    Yes, I have fond memories of tracking down a bug caused by exactly this in a Fortran program 20-some years ago. Somebody inadvertantly redefined the constant "1" to be "2". Of course the problem didn't show up until many lines later in the code. And so I was doing dumps going, "Okay, so now X=3, we add 1 to it ... and how did it end up being 5? I must have missed another update ..."

    Crap, that broke this fix (again):

    ThomasP:
    COMMENT_FRIST:
    COMMENT_FRIST = 3;

    Fixed.

  • ionine (unregistered)
    public static final String ONE_STRING = "9";
    

    beautiful

  • Yosemite Bear (unregistered) in reply to ionine
    ionine:
    public static final String ONE_STRING = "9";

    beautiful

    double rainbow = 180.0;
    
  • qbolec (unregistered) in reply to Big Excel Sheet
    Big Excel Sheet:
    Using,

    malloc(4 * sizeof(int) + sizeof(void *));

    might indicate a NULL terminator, whereas,

    malloc(4 * sizeof(int) + 1);

    is more likely to indicate a nul terminator.

    This is intriguing, how could you have \0 to be a terminator of an array of ints? How would the code that handles that look like? How would you store values larger than 2^24 and divisible by 256?

  • qbolec (unregistered) in reply to Ole The Swedish Sawmill Operator
    Ole The Swedish Sawmill Operator:
    qbolec:
    I actually wrote something like that, it was:

    const int NUMBER_OF_FINGERS = 8;

    FTFY

    By proving my code to be not portable (at least I fail at i18n), you have also brought to my attention the reason why English part of the word can not grasp the concepts of Metric System. It must be very difficult when you have 8 fingers.

  • Josh (unregistered)

    My favorite part is how most of the readers here don't understand Java enough to make informed comments on CodeSODs that contain them (I think that goes for the admins too).

  • not an idiot (unregistered) in reply to argh

    Don't u guys ever sleep? Perhaps a new joke next time at least? Is it too much to ask?

    No, we're up late at night, learning to spell the word 'you'.

  • Edward Royce (unregistered)

    Hmmmmm.

    public static final int MEANING_OF_LIFE = 42;

  • (cs) in reply to argh
    argh:
    the beholder:
    public static final int INTEGER_FRIST = 1;

    Don't u guys ever sleep? Perhaps a new joke next time at least? Is it too much to ask?

    Remember you're dealing with pure retardation there...

  • uuang (unregistered) in reply to Paula
    Paula:
    UPPERCASE_T_STRING + LOWERCASE_H_STRING + LOWERCASE_A_STRING + LOWERCASE_T_STRING + ONE_SPACE_STRING + LOWERCASE_I_STRING + LOWERCASE_S_STRING + ONE_SPACE_STRING + LOWERCASE_B_STRING + LOWERCASE_R_STRING + LOWERCASE_I_STRING + LOWERCASE_L_STRING + LOWERCASE_L_STRING + LOWERCASE_A_STRING + LOWERCASE_N_STRING + LOWERCASE_T_STRING + EXCLAMATION_MARK_STRING

    +1024

  • Nothing's New Under The Sun (unregistered)

    This is hardly new...

    The primary purpose of the DATA statement is to give names to constants; instead of referring to pi as 3.141592653589793 at every appearance, the variable PI can be given that value with a DATA statement and used instead of the longer form of the constant. This also simplifies modifying the program, should the value of pi change.

    -- Early FORTRAN manual for Xerox Computers -- http://en.wikiquote.org/wiki/Fortran

  • (cs) in reply to Nothing's New Under The Sun
    Nothing's New Under The Sun:
    This is hardly new...

    The primary purpose of the DATA statement is to give names to constants; instead of referring to pi as 3.141592653589793 at every appearance, the variable PI can be given that value with a DATA statement and used instead of the longer form of the constant. This also simplifies modifying the program, should the value of pi change.

    -- Early FORTRAN manual for Xerox Computers -- http://en.wikiquote.org/wiki/Fortran

    Wow man, you just strawmanned into the void. Nobody claimed this to be new...just crap.

  • Sydney (unregistered) in reply to Edward Royce
    Edward Royce:
    Hmmmmm.

    public static final int THE_ULTIMATE_ANSWER_TO_THE_ULITIMATE_QUESTION_OF_LIFE_THE_UNIVERSE_AND_EVERYTHING = 42;

    FTFY

  • neminem (unregistered) in reply to hoodaticus
    hoodaticus:
    You need a better sarcasm detector dude. There is not a single non-sarcastic sentence in the entire article.
    the article:
    The problem with using "FOUR" is that, like "4", it's a Magic Constant.

    That sentence is not sarcastic, it's entirely true. Using FOUR is not really any better than using the integer 4.

  • (cs) in reply to NoAstronomer
    NoAstronomer:
    Larry:

    TRWTF is that Java has no way to change constant values dynamically.

    LMAO That had me spraying coffee over my keyboard. Should be a featured comment.

    If only more languages had the ability to change constants on the fly. It's the way of the future.

    Java does have a way of doing this. It's called reflection.

    Thanks to some particularly evil use (as an experiment, I was proving a point and destroyed the code soon after) I managed to get

    System.out.println("Hello World!");

    to output the string "Goodbye All!".

  • The Nerve (unregistered) in reply to paulm
    paulm:
    NoAstronomer:
    Larry:

    TRWTF is that Java has no way to change constant values dynamically.

    LMAO That had me spraying coffee over my keyboard. Should be a featured comment.

    If only more languages had the ability to change constants on the fly. It's the way of the future.

    Java does have a way of doing this. It's called reflection.

    Thanks to some particularly evil use (as an experiment, I was proving a point and destroyed the code soon after) I managed to get

    System.out.println("Hello World!");

    to output the string "Goodbye All!".

    Please explain how you did this using only reflection and not making any use of the classloader. If you did this on a webserver or something else with a modified JVM, then nevermind.

    Without modifying the JVM, I can pretty much guarantee that you cannot set 3 = 4 application-wide as demonstrated in the FORTRAN example above.

  • The Nerve (unregistered) in reply to The Nerve

    This would be pretty easy to do without reflection. System has a

    setOut
    method, which would allow you to set it with your own PrintStream class. You could use Proxy (class) to create a Proxy (design pattern) that pointed back to
    System.getOut
    , but it's no more elegant than the hard-coded solution, and I doubt would meet Larry's definition.

    In other words: not a dynamically-defined constant: dynamically-modified static source code.

  • Herby (unregistered) in reply to Zylon
    Zylon:

    As an aside, it was actually pretty smart to do this sort of thing in Ye Olde 8-bit Atari BASIC. Numeric literals consumed six bytes in the code, but variable references only took two bytes, so you could save a lot of space in large programs by converting all commonly-used numbers to variables.

    100 N1=1:N2=N1+N1:N3=N2+N1:N4=N3+N1:N5=N4+N1

    Ahhh, memories...

    It gets WORSE. On a recent project (that is still actively being developed) I worked on, they are using Fortran. The original program dates back to the 70's or so, and they thought that this was the case even in Fortran 66 (that is what they originally used). There was a common block specifically setup to have all sorts of constants that could be globally referenced. Among these were such things as 0.0, 1.0, PI, .5 and all that. It was thought that this would reduce the code size and be more "efficient". The problem is that this is a false assumption, as it took MORE code to reference these constants that it saved in having them in a single place. It was a BIG FALSE ECONOMY. Some original programmer (back over 30 years or so) never took the time to see the difference, and crazy follow on programmers continued the silly practice. I for one made an effort to personally remove these when I saw them.

    Lord help us if the value of PI gets changed to 3, and all the planes fall out of the sky (that is where the program is used).

    Ph, and they thought it would be more efficient to do their own number formatting as well, another waste of time and resources.

  • (cs)

    What you're all discussing here are MANIFEST constants.

    And they ARE very useful things. Much of my software uses them.

    BUT they need to be named for what they represent, and NEVER for their value!

    For example: MIN_SONG_LENGTH_SECONDS = 67; and NOT SIXTY_SEVEN = 67; (!!!)

  • Mike (unregistered)

    My eyes! The goggles do nothing!

  • John Muller (unregistered)

    I really liked the 'magic' numbers I read about recently used in 'Montgomery' division

    like 1431655766 and 613566757 (assuming ints are 32 bit, and longs are 64)

    (((int)x*(long)143655766)>>32) == x/3 (((int)x*(long)613566757)>>32) == x/7

    Many compilers make this optimization automatically when dividing int by other contants ints. I used it manually once for a small performance gain in a program that had to divide ints by other ints in a narrow range (3,4 or 5)

  • (cs)

    I am amused and appalled at this programmer enthusiastically adopting the principle of magic numbers while completely failing to understand the concept.

Leave a comment on “Avoiding Magic Constants”

Log In or post as a guest

Replying to comment #:

« Return to Article