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

David Gobbi david.gobbi at gmail.com
Thu Jun 2 18:29:58 EDT 2011


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
>
>
>



More information about the vtk-developers mailing list