[vtk-developers] vtkMath::Ceil() and vtkMath::Floor()

Philippe Pébay pppebay at sandia.gov
Thu Jun 2 19:09:34 EDT 2011


David

Yes, the former. So, what I meant was that we may have, the following situation:

* x and y are doubles, different in FP representation (but very close, say just above machine epsilon)
* but yet static_cast<int>( x ) is the same as static_cast<int>( y )

and thus the composition of static_cast<double> with static_cast<int> is not the identity. Which may be entirely fine 
for most cases. But this becomes a feature which is worth being documented, since those trailing bits are thrown away on 
purpose as you said.

Now it might very well be that this exactly maps what ceil() and floor() do on all platforms, but I am not sure.

Thanks
Philippe

On 06/02/2011 03:50 PM, David Gobbi wrote:
> Just a quick follow up: when you say trailing bits, do you mean the
> trailing bits after those that represent an integer value, or do you
> mean the bits that might exist beyond the precision of double (i.e.
> extended precision).  I was assuming the former.
>
>   - David
>
>
> On Thu, Jun 2, 2011 at 4:29 PM, David Gobbi<david.gobbi at gmail.com>  wrote:
>> Hi Philippe,
>>
>> The trailing bits are important in this line:
>> int g = ( x<  0 );
>> which compares the original "x" against zero.
>>
>> But the static_cast<int>(x) throws away all trailing bits on purpose,
>> the intent of the double cast is to check whether throwing away the
>> trailing bits changes the value of the double.
>>
>>   - David
>>
>>
>> On Thu, Jun 2, 2011 at 4:22 PM, Philippe Pébay<pppebay at sandia.gov>  wrote:
>>> Hello David,
>>>
>>> Thanks for the explanation. Also, sorry for the typo, I meant "double cast"
>>> (not "double truncation").
>>>
>>> My question was with the != comparison between x and static_cast<double>(
>>> static_cast<int>( x ) ).
>>>
>>> So, as I understand your answer, the intent is effectively to give a
>>> definition of what it means
>>> to be an integer, and in this case, it means that static_cast<double>(
>>> static_cast<int>( x ) ) is the same as x.
>>>
>>> What I don't understand here is what happens to the trailing bits, which are
>>> still significant with respect to machine epsilon. What will happen when
>>> casting x to int?
>>>
>>> Thanks
>>> Philippe
>>>
>>>
>>> On 06/02/2011 03:01 PM, David Gobbi wrote:
>>>>
>>>> Hi Philippe,
>>>>
>>>> There is only one truncation, not two.  For Floor() the explanation is:
>>>>
>>>> x is input (a double, or maybe extended precision in FPU register)
>>>>
>>>> // step 1: truncate to integer
>>>> int r = static_cast<int>(x);
>>>>
>>>> // step 2: check if x can be represented exactly as an int,
>>>> // put the boolean result "1" or "0" in variable "n"
>>>> int n = ( x != static_cast<double>(r) );
>>>>
>>>> We know that the integer "r" can be represented exactly by
>>>> a double, and so the above checks if "x" can, in turn, be
>>>> represented exactly by an int.
>>>>
>>>> // step 3: check if x is above/below zero, put the boolean
>>>> // result "1" or "0" in variable "g"
>>>> int g = ( x<    0 );
>>>>
>>>> // step 4: subtract 1 from the result if steps 2 and 3 are true
>>>> return r - ( n&    g );
>>>>
>>>>
>>>> The idea behind this is the following: when "x" is>= 0, doing
>>>> static_cast<int>(x) is exactly the same as floor(x).  But if "x"
>>>> is less than zero (step 3) we need to subtract one unless "x"
>>>> can be represented exactly by an int (step 2).
>>>>
>>>> The purpose of step 4 is to avoid any branching in the code,
>>>> as compared to doing the same logic with "if" statements.
>>>>
>>>>   - David
>>>>
>>>>
>>>>
>>>> On Thu, Jun 2, 2011 at 3:25 PM, Philippe Pébay<pppebay at sandia.gov>    wrote:
>>>>>
>>>>> Hello David,
>>>>>
>>>>> Thanks for the prompt answer.
>>>>>
>>>>> I still don't understand the double truncation for Floor() and Ceil():
>>>>> why
>>>>> cast the readings to int first, and then to double again? I am not sure I
>>>>> understand what "exact results" mean in this contest, as the cast itself
>>>>> changes the nature of the representation, and a double cast does not, as
>>>>> far
>>>>> as I know at least, amount to an identity operation.
>>>>>
>>>>> Or does it? Are you saying that static_cast<double>( static_cast<int>( x
>>>>> ) )
>>>>> has always the exact same FP representation than x?
>>>>>
>>>>> Thanks
>>>>> Philippe
>>>>>
>>>>> On 06/02/2011 02:20 PM, David Gobbi wrote:
>>>>>>
>>>>>> Hi Philippe,
>>>>>>
>>>>>> I wrote the Floor() and Ceil() functions a few months ago.  They are
>>>>>> written specifically for speed.  For double values that are within the
>>>>>> int range, they give exact results.
>>>>>>
>>>>>> The vtkMath::Round() is fast, too, but the operation that it performs
>>>>>> does not conform to any of the IEEE 754 standard rounding modes.
>>>>>>
>>>>>>   - David
>>>>>>
>>>>>> On Thu, Jun 2, 2011 at 3:09 PM, Philippe Pébay<pppebay at sandia.gov>
>>>>>>   wrote:
>>>>>>>
>>>>>>> ... a clarification of what I asked earlier...
>>>>>>>
>>>>>>> By "different intent" I was referring to the fact that vtkMath's
>>>>>>> Floor()
>>>>>>> and
>>>>>>> Ceil() perform something which I find a little intriguing, namely,
>>>>>>> casting a
>>>>>>> double to an int, and then re-casting the latter to a double to perform
>>>>>>> a
>>>>>>> double-double equality comparison, which, I would venture to say,
>>>>>>> should
>>>>>>> be
>>>>>>> avoided whenever possible.
>>>>>>>
>>>>>>> On the other hand, Round() does not do this double casting but directly
>>>>>>> performs double-double inequality comparison, and a single cast to an
>>>>>>> int
>>>>>>> at
>>>>>>> the end. This seems much better to me.
>>>>>>>
>>>>>>> Thanks
>>>>>>> Philippe
>>>>>>>
>>>>>>> On 06/02/2011 02:04 PM, Philippe Pébay wrote:
>>>>>>>>
>>>>>>>> Hello,
>>>>>>>>
>>>>>>>> I was contemplating using vtkMath::Ceil() and vtkMath::Floor() in some
>>>>>>>> of my code, instead of the standard ceil() and floor(). However they
>>>>>>>> appear to be written with a slightly different intent than
>>>>>>>> vtkMath::Round(). Can someone comment on that?
>>>>>>>>
>>>>>>>> Thanks
>>>>>>>> Philippe
>>>>>>>
>>>>>>>
>>>>>>> --
>>>>>>> Philippe Pébay
>>>>>>> Sandia National Laboratories
>>>>>>>
>>>>>>>
>>>>>>> _______________________________________________
>>>>>>> Powered by www.kitware.com
>>>>>>>
>>>>>>> Visit other Kitware open-source projects at
>>>>>>> http://www.kitware.com/opensource/opensource.html
>>>>>>>
>>>>>>> Follow this link to subscribe/unsubscribe:
>>>>>>> http://www.vtk.org/mailman/listinfo/vtk-developers
>>>>>>>
>>>>>>>
>>>>>>
>>>>>
>>>>>
>>>>> --
>>>>> Philippe Pébay
>>>>> Sandia National Laboratories
>>>>>
>>>>>
>>>>>
>>>>
>>>
>>>
>>> --
>>> Philippe Pébay
>>> Sandia National Laboratories
>>>
>>>
>>>
>>
>


-- 
Philippe Pébay
Sandia National Laboratories





More information about the vtk-developers mailing list