File: vtkFastNumericConversion.cxx

package info (click to toggle)
vtk6 6.1.0%2Bdfsg2-6
  • links: PTS, VCS
  • area: main
  • in suites: jessie, jessie-kfreebsd
  • size: 165,164 kB
  • ctags: 226,428
  • sloc: cpp: 1,354,490; ansic: 730,748; python: 227,134; tcl: 48,285; xml: 8,290; yacc: 4,832; java: 3,827; perl: 3,108; lex: 1,809; sh: 1,437; asm: 471; makefile: 229
file content (119 lines) | stat: -rw-r--r-- 4,595 bytes parent folder | download | duplicates (4)
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
/*=========================================================================

  Program:   Visualization Toolkit
  Module:    vtkFastNumericConversion.cxx

  Copyright (c) Ken Martin, Will Schroeder, Bill Lorensen
  All rights reserved.
  See Copyright.txt or http://www.kitware.com/Copyright.htm for details.

     This software is distributed WITHOUT ANY WARRANTY; without even
     the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR
     PURPOSE.  See the above copyright notice for more information.

=========================================================================*/
// .NAME vtkFastNumericConversion - Enables fast conversion of floating point to fixed point
// .SECTION Description
// vtkFastNumericConversion uses a portable (assuming IEEE format) method for converting single and
// double precision floating point values to a fixed point representation. This allows fast
// integer flooring on platforms, such as Intel X86, in which CPU floating point flooring
// algorithms are very slow. It is based on the techniques described in Chris Hecker's article,
// "Let's Get to the (Floating) Point", in Game Developer Magazine, Feb/Mar 1996, and the
// techniques described in Michael Herf's website, http://www.stereopsis.com/FPU.html.
// The Hecker article can be found at http://www.d6.com/users/checker/pdfs/gdmfp.pdf.
// Unfortunately, each of these techniques is incomplete, and doesn't floor properly,
// in a way that depends on how many bits are reserved for fixed point fractional use, due to
// failing to properly account for the default round-towards-even rounding mode of the X86. Thus,
// my implementation incorporates some rounding correction that undoes the rounding that the
// FPU performs during denormalization of the floating point value. Note that
// the rounding affect I'm talking about here is not the effect on the fistp instruction,
// but rather the effect that occurs during the denormalization of a value that occurs when
// adding it to a much larger value. The bits must be shifted to the right, and when a "1" bit
// falls off the edge, the rounding mode determines what happens next, in order
// to avoid completely "losing" the 1-bit. Furthermore, my implementation works on Linux, where the
// default precision mode is 64-bit extended precision.

// This class is contributed to VTK by Chris Volpe of Applied Research Associates, Inc.
// (My employer requires me to say that -- CRV)


#include "vtkFastNumericConversion.h"
#include "vtkObjectFactory.h"

#include "vtkMath.h"

vtkStandardNewMacro(vtkFastNumericConversion);

vtkFastNumericConversion::vtkFastNumericConversion()
{
#ifdef VTK_TEST_HACK_TO_EMULATE_LINUX_UNDER_WINDOWS
  _controlfp( _PC_64, MCW_PC );
#endif

  this->fixRound = 0;
  this->internalReservedFracBits = 0;
  this->fracMask = 0;
  this->fpDenormalizer = 0;

#ifndef VTK_LEGACY_SILENT
  vtkWarningMacro("Class vtkFastNumericConversion was depecated for VTK 6.0 "
                  "and will be removed in a future version.");
#endif
}

#ifndef VTK_LEGACY_SILENT
int vtkFastNumericConversion::QuickFloor(const double &val)
{
  static int once = 0;
  if (!once)
    {
    VTK_LEGACY_REPLACED_BODY(vtkFastNumericConversion::QuickFloor, "VTK 6.0",
                             vtkMath::Floor);
    once = 1;
    }
  return vtkFastNumericConversion::QuickFloorInline(val);
}

int vtkFastNumericConversion::SafeFloor(const double &val)
{
  static int once = 0;
  if (!once)
    {
    VTK_LEGACY_REPLACED_BODY(vtkFastNumericConversion::SafeFloor, "VTK 6.0",
                             vtkMath::Floor);
    once = 1;
    }
  return vtkFastNumericConversion::SafeFloorInline(val);
}

int vtkFastNumericConversion::Round(const double &val)
{
  static int once = 0;
  if (!once)
    {
    VTK_LEGACY_REPLACED_BODY(vtkFastNumericConversion::Round, "VTK 6.0",
                             vtkMath::Round);
    once = 1;
    }
  return vtkFastNumericConversion::RoundInline(val);
}
#endif

void vtkFastNumericConversion::InternalRebuild()
{
  int i;
  this->fixRound=.5;
  for (i=this->internalReservedFracBits; i; i--)
    {
    this->fixRound *= .5;
    }
  this->fracMask = (1<<this->internalReservedFracBits)-1;
  this->fpDenormalizer = (static_cast<unsigned long>(1) << (52-30-this->internalReservedFracBits)) *
    this->two30() * this->BorrowBit();
  this->epTempDenormalizer = this->fpDenormalizer * (static_cast<unsigned long>(1) << (63-52));
}

void vtkFastNumericConversion::PrintSelf(ostream &os, vtkIndent indent)
{
  os << indent << "ReservedFracBits: " << this->internalReservedFracBits << endl;
}