The application.



  • I came across this line in the code of the Asp.Net website I support, I think it sums up my daily battle against The Application.

     int pos = (int)Math.Floor(((TimeSpan)(row.Maturity.Subtract(DateTime.Today))).Days / 7.0);



  • So "pos" stands for...?



  • @HighlyPaidContractor said:

    So "pos" stands for...?

    Number of weeks until some date, the TimeSpan cast is not needed, and AFAIK casting to int has the same result as Math.Floor. (except for negative cases)

    int pos = row.Maturity.Subtract(DateTime.Today).Days / 7;


  • @XIU said:

    casting to int has the same result as Math.Floor. (except for negative cases)

     

     

    Strangely enough, Math.Floor doesn't return an int, but a double or decimal. Can't quite put my finger on why but probably so they can return double.NegativeInfinity if needed.

    http://msdn.microsoft.com/en-us/library/k7ycc7xh.aspx



  • It returns a double because it takes a double. If you passed a double that's outside the range of an integer, how could the result be represented?



  • So there's a redundant cast and too many brackets. I see that all the time in the code I have to maintain, and while I'm hardly thrilled with it, I've come across far worse constructs.



  • @smxlong said:

    It returns a double because it takes a double. If you passed a double that's outside the range of an integer, how could the result be represented?
     

    Right.



  • @smxlong said:

    It returns a double because it takes a double. If you passed a double that's outside the range of an integer, how could the result be represented?

    So now it's just a rounding error pitfall instead?



  • @Faxmachinen said:

    So now it's just a rounding error pitfall instead?

    Ghetto Edit: After thinking and reading about it, there's no way to get a rounding error when rounding a float to the nearest whole number, so nevermind.



  • @smxlong said:

    It returns a double because it takes a double. If you passed a double that's outside the range of an integer, how could the result be represented?
     

     By an error. Unless the answer happens to be exactly expressable in double-precision floating point, then floor cannot return an accurate answer. floor(>MAXINT) (or really floor(greater than the value where double i != double( i+1 ), I cannot recall what that is called) ) is going to be either wrong, or a no-op.

     Mind you, it probably cannot return an accurate answer most of the time, which is another reason why it should return an integer. At least it could then do as it says on the tin, not return a double that is aproximately equal to the required integer.



  • @robbak said:

    Mind you, it probably cannot return an accurate answer most of the time

    The question of whether it's "most of the time" or not entirely hinges on the domain of you application, and the scope of the numbers you might encounter therein...



  • Before you rant about standard libraries, you better RTFM.

    First, doubles have a precision of 52 bits and can therefore represent any 32bit integer exactly. In fact, they are accurate for all integers in the range [-2^52+1, 2^52-1], which a int cannot even represent.
    Second, if a double value is bigger than 2^52-1, it will always be a integral number and floor will always be a noop.
    Therefore the value returned by floor is always a accurate. (In the sense, that it's an integral number).

    Your approach on the other hand violates the principle of least surprise by casting to an int, unnecessarily losing precision and throwing an exception on overflows (what alternative would you have?).


Log in to reply