0029399: Optimize reading of floating point values from text strings IR-2018-01-26
authorabv <abv@opencascade.com>
Sun, 24 Dec 2017 06:44:04 +0000 (09:44 +0300)
committerapn <apn@opencascade.com>
Fri, 26 Jan 2018 17:11:03 +0000 (20:11 +0300)
Function Strtod() is reimplemented using open source (MIT-style license) code by David M. Gay instead of strtod() provided by standard run-time library. This improves its performance by 3-10 times.

Functions Atof(), Strtod(), Printf(), Sprintf(), Fprintf() are declared as extern "C" to be usable from C programs.

Strtod() is used in Interface_FileReaderData::Fastof() and in RWStl_Reader to accelerate their work.

DRAW command QATestAtof and test perf fclasses strtod are added to check correctness and performance of Strtod().
Test perf draw restore is added to monitor performance of reading BREP files.

Minor off-topic corrections:
- method Standard_GUID::Assign (const Standard_UUID&) is implemented (was empty);
- Precision.hxx is included in BRepMesh_Vertex.hxx that uses it.

16 files changed:
dox/overview/overview.md
src/BRepMesh/BRepMesh_Vertex.hxx
src/Interface/Interface_FileReaderData.cxx
src/QANCollection/QANCollection_Test.cxx
src/RWStl/RWStl_Reader.cxx
src/Standard/FILES
src/Standard/Standard_CString.cxx
src/Standard/Standard_CString.hxx
src/Standard/Standard_GUID.cxx
src/Standard/Standard_SStream.cxx [deleted file]
src/Standard/Standard_Strtod.cxx
src/Standard/Standard_UUID.cxx [deleted file]
tests/de/step_1/A3
tests/de/step_3/E6
tests/perf/draw/restore [new file with mode: 0644]
tests/perf/fclasses/strtod [new file with mode: 0644]

index 5a79b3c..1945bc6 100644 (file)
@@ -136,6 +136,9 @@ FreeImage is easy to use, fast, multithreading safe, compatible with all 32-bit
 and cross-platform (works both with Linux and Mac OS X). FreeImage is optionally used by OCCT to work
 with images, on conditions of the FreeImage Public License (FIPL) (http://freeimage.sourceforge.net/freeimage-license.txt).
 
+**David M. Gay's floating point routines** (dtoa.c) are used for fast reading of floating point values from text strings.
+These routines are available under MIT-like license (see http://www.netlib.org/fp/).
+
 **CMake** is an open-source, cross-platform family of tools designed to build, test and package software. CMake is used to control the software compilation process using simple platform and compiler independent configuration files, and generate native makefiles and workspaces that can be used in the compiler environment of your choice. 
 OCCT uses CMake as a build system. CMake is available under BSD 3-Clause license. See more at https://cmake.org/
 
index 7cb7d72..c66bcf6 100644 (file)
 #ifndef _BRepMesh_Vertex_HeaderFile
 #define _BRepMesh_Vertex_HeaderFile
 
-#include <Standard.hxx>
-#include <Standard_DefineAlloc.hxx>
-#include <Standard_Macro.hxx>
-#include <gp_XY.hxx>
 #include <BRepMesh_DegreeOfFreedom.hxx>
+#include <gp_XY.hxx>
+#include <Precision.hxx>
 
 //! Light weighted structure representing vertex 
 //! of the mesh in parametric space. Vertex could be 
index 57b9f3e..4349a63 100644 (file)
@@ -241,210 +241,7 @@ void Interface_FileReaderData::Destroy ()
 {
 }
 
-
-#define MAXCHIF 80
-
-static const Standard_Real vtab[] =
-{ 1.,     2.,     3.,     4., 5., 6., 7.,     8., 9.,
-  10.,    20.,    30.,    40., 50., 60., 70.,    80., 90.,
-  100.,   200.,   300.,   400., 500., 600., 700.,   800., 900.,
-  1000.,  2000.,  3000.,  4000., 5000., 6000., 7000.,  8000., 9000.,
-  10000., 20000., 30000., 40000., 50000., 60000., 70000., 80000., 90000.,
-  1.E+05, 2.E+05, 3.E+05, 4.E+05, 5.E+05, 6.E+05, 7.E+05, 8.E+05, 9.E+05,
-  1.E+06, 2.E+06, 3.E+06, 4.E+06, 5.E+06, 6.E+06, 7.E+06, 8.E+06, 9.E+06,
-  1.E+07, 2.E+07, 3.E+07, 4.E+07, 5.E+07, 6.E+07, 7.E+07, 8.E+07, 9.E+07,
-  1.E+08, 2.E+08, 3.E+08, 4.E+08, 5.E+08, 6.E+08, 7.E+08, 8.E+08, 9.E+08,
-  1.E+09, 2.E+09, 3.E+09, 4.E+09, 5.E+09, 6.E+09, 7.E+09, 8.E+09, 9.E+09,
-  1.E+10, 2.E+10, 3.E+10, 4.E+10, 5.E+10, 6.E+10, 7.E+10, 8.E+10, 9.E+10,
-  1.E+11, 2.E+11, 3.E+11, 4.E+11, 5.E+11, 6.E+11, 7.E+11, 8.E+11, 9.E+11,
-  1.E+12, 2.E+12, 3.E+12, 4.E+12, 5.E+12, 6.E+12, 7.E+12, 8.E+12, 9.E+12,
-  1.E+13, 2.E+13, 3.E+13, 4.E+13, 5.E+13, 6.E+13, 7.E+13, 8.E+13, 9.E+13,
-  1.E+14, 2.E+14, 3.E+14, 4.E+14, 5.E+14, 6.E+14, 7.E+14, 8.E+14, 9.E+14,
-  1.E+15, 2.E+15, 3.E+15, 4.E+15, 5.E+15, 6.E+15, 7.E+15, 8.E+15, 9.E+15,
-  1.E+16, 2.E+16, 3.E+16, 4.E+16, 5.E+16, 6.E+16, 7.E+16, 8.E+16, 9.E+16,
-  1.E+17, 2.E+17, 3.E+17, 4.E+17, 5.E+17, 6.E+17, 7.E+17, 8.E+17, 9.E+17,
-  1.E+18, 2.E+18, 3.E+18, 4.E+18, 5.E+18, 6.E+18, 7.E+18, 8.E+18, 9.E+18,
-  1.E+19, 2.E+19, 3.E+19, 4.E+19, 5.E+19, 6.E+19, 7.E+19, 8.E+19, 9.E+19,
-  1.E+20, 2.E+20, 3.E+20, 4.E+20, 5.E+20, 6.E+20, 7.E+20, 8.E+20, 9.E+20,
-  1.E+21, 2.E+21, 3.E+21, 4.E+21, 5.E+21, 6.E+21, 7.E+21, 8.E+21, 9.E+21,
-  1.E+22, 2.E+22, 3.E+22, 4.E+22, 5.E+22, 6.E+22, 7.E+22, 8.E+22, 9.E+22,
-  1.E+23, 2.E+23, 3.E+23, 4.E+23, 5.E+23, 6.E+23, 7.E+23, 8.E+23, 9.E+23,
-  1.E+24, 2.E+24, 3.E+24, 4.E+24, 5.E+24, 6.E+24, 7.E+24, 8.E+24, 9.E+24,
-  1.E+25, 2.E+25, 3.E+25, 4.E+25, 5.E+25, 6.E+25, 7.E+25, 8.E+25, 9.E+25,
-  1.E+26, 2.E+26, 3.E+26, 4.E+26, 5.E+26, 6.E+26, 7.E+26, 8.E+26, 9.E+26,
-  1.E+27, 2.E+27, 3.E+27, 4.E+27, 5.E+27, 6.E+27, 7.E+27, 8.E+27, 9.E+27,
-  1.E+28, 2.E+28, 3.E+28, 4.E+28, 5.E+28, 6.E+28, 7.E+28, 8.E+28, 9.E+28,
-  1.E+29, 2.E+29, 3.E+29, 4.E+29, 5.E+29, 6.E+29, 7.E+29, 8.E+29, 9.E+29,
-  1.E+30, 2.E+30, 3.E+30, 4.E+30, 5.E+30, 6.E+30, 7.E+30, 8.E+30, 9.E+30,
-  1.E+31, 2.E+31, 3.E+31, 4.E+31, 5.E+31, 6.E+31, 7.E+31, 8.E+31, 9.E+31,
-  1.E+32, 2.E+32, 3.E+32, 4.E+32, 5.E+32, 6.E+32, 7.E+32, 8.E+32, 9.E+32,
-  1.E+33, 2.E+33, 3.E+33, 4.E+33, 5.E+33, 6.E+33, 7.E+33, 8.E+33, 9.E+33,
-  1.E+34, 2.E+34, 3.E+34, 4.E+34, 5.E+34, 6.E+34, 7.E+34, 8.E+34, 9.E+34,
-  1.E+35, 2.E+35, 3.E+35, 4.E+35, 5.E+35, 6.E+35, 7.E+35, 8.E+35, 9.E+35,
-  1.E+36, 2.E+36, 3.E+36, 4.E+36, 5.E+36, 6.E+36, 7.E+36, 8.E+36, 9.E+36,
-  1.E+37, 2.E+37, 3.E+37, 4.E+37, 5.E+37, 6.E+37, 7.E+37, 8.E+37, 9.E+37,
-  1.E+38, 2.E+38, 3.E+38, 4.E+38, 5.E+38, 6.E+38, 7.E+38, 8.E+38, 9.E+38,
-  1.E+39, 2.E+39, 3.E+39, 4.E+39, 5.E+39, 6.E+39, 7.E+39, 8.E+39, 9.E+39,
-  1.E+40, 2.E+40, 3.E+40, 4.E+40, 5.E+40, 6.E+40, 7.E+40, 8.E+40, 9.E+40,
-  1.E+41, 2.E+41, 3.E+41, 4.E+41, 5.E+41, 6.E+41, 7.E+41, 8.E+41, 9.E+41,
-  1.E+42, 2.E+42, 3.E+42, 4.E+42, 5.E+42, 6.E+42, 7.E+42, 8.E+42, 9.E+42,
-  1.E+43, 2.E+43, 3.E+43, 4.E+43, 5.E+43, 6.E+43, 7.E+43, 8.E+43, 9.E+43,
-  1.E+44, 2.E+44, 3.E+44, 4.E+44, 5.E+44, 6.E+44, 7.E+44, 8.E+44, 9.E+44,
-  1.E+45, 2.E+45, 3.E+45, 4.E+45, 5.E+45, 6.E+45, 7.E+45, 8.E+45, 9.E+45,
-  1.E+46, 2.E+46, 3.E+46, 4.E+46, 5.E+46, 6.E+46, 7.E+46, 8.E+46, 9.E+46,
-  1.E+47, 2.E+47, 3.E+47, 4.E+47, 5.E+47, 6.E+47, 7.E+47, 8.E+47, 9.E+47,
-  1.E+48, 2.E+48, 3.E+48, 4.E+48, 5.E+48, 6.E+48, 7.E+48, 8.E+48, 9.E+48,
-  1.E+49, 2.E+49, 3.E+49, 4.E+49, 5.E+49, 6.E+49, 7.E+49, 8.E+49, 9.E+49,
-  1.E+50, 2.E+50, 3.E+50, 4.E+50, 5.E+50, 6.E+50, 7.E+50, 8.E+50, 9.E+50,
-  1.E+51, 2.E+51, 3.E+51, 4.E+51, 5.E+51, 6.E+51, 7.E+51, 8.E+51, 9.E+51,
-  1.E+52, 2.E+52, 3.E+52, 4.E+52, 5.E+52, 6.E+52, 7.E+52, 8.E+52, 9.E+52,
-  1.E+53, 2.E+53, 3.E+53, 4.E+53, 5.E+53, 6.E+53, 7.E+53, 8.E+53, 9.E+53,
-  1.E+54, 2.E+54, 3.E+54, 4.E+54, 5.E+54, 6.E+54, 7.E+54, 8.E+54, 9.E+54,
-  1.E+55, 2.E+55, 3.E+55, 4.E+55, 5.E+55, 6.E+55, 7.E+55, 8.E+55, 9.E+55,
-  1.E+56, 2.E+56, 3.E+56, 4.E+56, 5.E+56, 6.E+56, 7.E+56, 8.E+56, 9.E+56,
-  1.E+57, 2.E+57, 3.E+57, 4.E+57, 5.E+57, 6.E+57, 7.E+57, 8.E+57, 9.E+57,
-  1.E+58, 2.E+58, 3.E+58, 4.E+58, 5.E+58, 6.E+58, 7.E+58, 8.E+58, 9.E+58,
-  1.E+59, 2.E+59, 3.E+59, 4.E+59, 5.E+59, 6.E+59, 7.E+59, 8.E+59, 9.E+59,
-  1.E+60, 2.E+60, 3.E+60, 4.E+60, 5.E+60, 6.E+60, 7.E+60, 8.E+60, 9.E+60,
-  1.E+61, 2.E+61, 3.E+61, 4.E+61, 5.E+61, 6.E+61, 7.E+61, 8.E+61, 9.E+61,
-  1.E+62, 2.E+62, 3.E+62, 4.E+62, 5.E+62, 6.E+62, 7.E+62, 8.E+62, 9.E+62,
-  1.E+63, 2.E+63, 3.E+63, 4.E+63, 5.E+63, 6.E+63, 7.E+63, 8.E+63, 9.E+63,
-  1.E+64, 2.E+64, 3.E+64, 4.E+64, 5.E+64, 6.E+64, 7.E+64, 8.E+64, 9.E+64,
-  1.E+65, 2.E+65, 3.E+65, 4.E+65, 5.E+65, 6.E+65, 7.E+65, 8.E+65, 9.E+65,
-  1.E+66, 2.E+66, 3.E+66, 4.E+66, 5.E+66, 6.E+66, 7.E+66, 8.E+66, 9.E+66,
-  1.E+67, 2.E+67, 3.E+67, 4.E+67, 5.E+67, 6.E+67, 7.E+67, 8.E+67, 9.E+67,
-  1.E+68, 2.E+68, 3.E+68, 4.E+68, 5.E+68, 6.E+68, 7.E+68, 8.E+68, 9.E+68,
-  1.E+69, 2.E+69, 3.E+69, 4.E+69, 5.E+69, 6.E+69, 7.E+69, 8.E+69, 9.E+69,
-  1.E+70, 2.E+70, 3.E+70, 4.E+70, 5.E+70, 6.E+70, 7.E+70, 8.E+70, 9.E+70,
-  1.E+71, 2.E+71, 3.E+71, 4.E+71, 5.E+71, 6.E+71, 7.E+71, 8.E+71, 9.E+71,
-  1.E+72, 2.E+72, 3.E+72, 4.E+72, 5.E+72, 6.E+72, 7.E+72, 8.E+72, 9.E+72,
-  1.E+73, 2.E+73, 3.E+73, 4.E+73, 5.E+73, 6.E+73, 7.E+73, 8.E+73, 9.E+73,
-  1.E+74, 2.E+74, 3.E+74, 4.E+74, 5.E+74, 6.E+74, 7.E+74, 8.E+74, 9.E+74,
-  1.E+75, 2.E+75, 3.E+75, 4.E+75, 5.E+75, 6.E+75, 7.E+75, 8.E+75, 9.E+75,
-  1.E+76, 2.E+76, 3.E+76, 4.E+76, 5.E+76, 6.E+76, 7.E+76, 8.E+76, 9.E+76,
-  1.E+77, 2.E+77, 3.E+77, 4.E+77, 5.E+77, 6.E+77, 7.E+77, 8.E+77, 9.E+77,
-  1.E+78, 2.E+78, 3.E+78, 4.E+78, 5.E+78, 6.E+78, 7.E+78, 8.E+78, 9.E+78,
-  1.E+79, 2.E+79, 3.E+79, 4.E+79, 5.E+79, 6.E+79, 7.E+79, 8.E+79, 9.E+79,
-  1.E+80, 2.E+80, 3.E+80, 4.E+80, 5.E+80, 6.E+80, 7.E+80, 8.E+80, 9.E+80,
-  1.E+81, 2.E+81, 3.E+81, 4.E+81, 5.E+81, 6.E+81, 7.E+81, 8.E+81, 9.E+81,
-  1.E+82, 2.E+82, 3.E+82, 4.E+82, 5.E+82, 6.E+82, 7.E+82, 8.E+82, 9.E+82,
-  1.E+83, 2.E+83, 3.E+83, 4.E+83, 5.E+83, 6.E+83, 7.E+83, 8.E+83, 9.E+83,
-  1.E+84, 2.E+84, 3.E+84, 4.E+84, 5.E+84, 6.E+84, 7.E+84, 8.E+84, 9.E+84,
-  1.E+85, 2.E+85, 3.E+85, 4.E+85, 5.E+85, 6.E+85, 7.E+85, 8.E+85, 9.E+85,
-  1.E+86, 2.E+86, 3.E+86, 4.E+86, 5.E+86, 6.E+86, 7.E+86, 8.E+86, 9.E+86,
-  1.E+87, 2.E+87, 3.E+87, 4.E+87, 5.E+87, 6.E+87, 7.E+87, 8.E+87, 9.E+87,
-  1.E+88, 2.E+88, 3.E+88, 4.E+88, 5.E+88, 6.E+88, 7.E+88, 8.E+88, 9.E+88,
-  1.E+89, 2.E+89, 3.E+89, 4.E+89, 5.E+89, 6.E+89, 7.E+89, 8.E+89, 9.E+89,
-  1.E+90, 2.E+90, 3.E+90, 4.E+90, 5.E+90, 6.E+90, 7.E+90, 8.E+90, 9.E+90,
-  1.E+91, 2.E+91, 3.E+91, 4.E+91, 5.E+91, 6.E+91, 7.E+91, 8.E+91, 9.E+91,
-  1.E+92, 2.E+92, 3.E+92, 4.E+92, 5.E+92, 6.E+92, 7.E+92, 8.E+92, 9.E+92,
-  1.E+93, 2.E+93, 3.E+93, 4.E+93, 5.E+93, 6.E+93, 7.E+93, 8.E+93, 9.E+93,
-  1.E+94, 2.E+94, 3.E+94, 4.E+94, 5.E+94, 6.E+94, 7.E+94, 8.E+94, 9.E+94,
-  1.E+95, 2.E+95, 3.E+95, 4.E+95, 5.E+95, 6.E+95, 7.E+95, 8.E+95, 9.E+95,
-  1.E+96, 2.E+96, 3.E+96, 4.E+96, 5.E+96, 6.E+96, 7.E+96, 8.E+96, 9.E+96,
-  1.E+97, 2.E+97, 3.E+97, 4.E+97, 5.E+97, 6.E+97, 7.E+97, 8.E+97, 9.E+97,
-  1.E+98, 2.E+98, 3.E+98, 4.E+98, 5.E+98, 6.E+98, 7.E+98, 8.E+98, 9.E+98,
-  1.E+99, 2.E+99, 3.E+99, 4.E+99, 5.E+99, 6.E+99, 7.E+99, 8.E+99, 9.E+99 };
-
-
-    Standard_Real Interface_FileReaderData::Fastof (const Standard_CString ligne)
+Standard_Real Interface_FileReaderData::Fastof (const Standard_CString ligne)
 {
-  Standard_Real val = 0., valdiv;
-  int i, jj, j, k, je, jx;
-  int chiffre[MAXCHIF];  int point, prem, moins, exp, grexp;
-  j = jj = je = jx = 0;
-  moins = exp = grexp = 0;
-  prem = MAXCHIF + 1;  point = -1;  //   ligne[MAXCHIF+1] = '\0';  fin forcee
-
-/*  Analyse de la ligne (reputee representer un Flottant)  */
-  for (i = 0; ; i ++) // critere d arret : cf '\0'
-  {
-    const char& car = ligne[i];
-/* critere d arret : ne pas l oublier, mais eviter de freiner le traitement
-   DONC, une fois en fin, plus une fois pour 1er passage
-    if (car == '\0')
-      {  if (point < 0) {  point = i; jx = point - prem; };  break;  }   */
-
-    if (prem > MAXCHIF)
-    {
-      if (car == '0') continue;
-      if (car == '.') {  point = i;  continue;  }
-      if (car == '+') continue;
-      if (car == '-') {  moins = 1;  continue;  }
-      if (car == '\0')
-      {
-        if (point < 0)
-        {
-          point = i;
-          jx = point - prem;
-        }
-        break;
-      }
-      if (car < 33)
-      {
-        continue;
-      }
-      prem = i;
-      if (point >= 0)
-      {
-        jx = point - prem + 1;
-      }
-    }
-    if (car > 48 && car <= 57)
-    {
-      chiffre[j] = car - 48;
-      jj = ++j; // j++ puis jj = j
-      continue;
-    }
-    if (car == '0') {  chiffre[j] = 0;  j ++;  continue;  }
-    if (car == '.') {  point = i;  jx = point - prem;  continue;  }
-    if ((car & 94) == 68) { // prend  : e E d D
-      je = i;     exp = atoi(&ligne[i+1]);     jx += exp;
-      if (exp < -100 || exp > 100)
-      {
-        grexp = 1;
-      }
-      break;
-    }
-    if (car == '\0')
-    {
-      if (point < 0)
-      {
-        point = i;
-        jx = point - prem;
-      }
-      break;
-    }
-  }
-
-/*  Interpretation  : on decale le Point Decimal selon l Exposant
-    Puis on considere par rapport a <jj>, <prem> :
-    chiffre[i, pour i <  point - prem] : partie entiere
-    chiffre[i, pour i >= point - prem] : partie decimale
-*/
-
-//  jx = (point < prem ? point - prem + 1 : point - prem) + exp;  deja calcule
-//        Puissance de 10 premiere decimale <0>
-//  limite : le PLUS PETIT SIGNIFIANT doit etre >= 1e-99
-  je = jx*9;
-  if (jx > jj) {
-    valdiv = 1.;
-    if (jx >= 100 || grexp) return Atof(ligne);  // issue de secours
-  } else {
-    k = jj*9;
-    if (jj >= 100 || grexp || (k-je >= 900)) return Atof(ligne);  // issue de secours
-    valdiv = vtab[k-je];
-    je = k;
-  }
-
-  je --;
-//  val = 0.;    mis a la creation
-  for (i = 0; i < jj; i ++) {
-    je -= 9;
-    const int& chif = chiffre[i];
-    if (chif != 0) val += vtab[chif+je];
-  }
-  if (valdiv != 1.) val = val/valdiv;
-  if (moins) val = -val;
-  return val;
+  return Strtod (ligne, 0);
 }
index 493a177..03e10cb 100644 (file)
@@ -22,6 +22,7 @@
 #include <gp_Pnt.hxx>
 
 #include <Precision.hxx>
+#include <Standard_Overflow.hxx>
 
 #include <NCollection_Vector.hxx>
 
@@ -863,6 +864,251 @@ static Standard_Integer QANColTestArrayMove (Draw_Interpretor& di, Standard_Inte
   return 0;
 }
 
+#include <math_BullardGenerator.hxx>
+#include <OSD_Timer.hxx>
+
+static inline double test_atof (const char* theStr) 
+{ 
+  return atof (theStr);
+}
+
+static inline double test_Atof (const char* theStr) 
+{ 
+  return Atof (theStr);
+}
+
+static inline double test_strtod (const char* theStr) 
+{ 
+  char *end;
+  return strtod (theStr, &end);
+}
+
+static inline double test_Strtod (const char* theStr) 
+{ 
+  char *end;
+  return Strtod (theStr, &end);
+}
+
+static inline double test_sscanf (const char* theStr) 
+{ 
+  double val = 0.;
+  sscanf (theStr, "%lf", &val);
+  return val; 
+}
+
+static int check_atof (const NCollection_Array2<char>& theStrings, const char* theFormat,
+                       double (*test_func)(const char*), Draw_Interpretor& di)
+{
+  int aNbErr = 0;
+  for (int i = 0; i < theStrings.UpperRow(); i++) 
+  {
+    const char *aStr= &theStrings(i,0);
+    char buff[256];
+    double aVal = test_func (aStr);
+    Sprintf (buff, theFormat, aVal);
+    if (strcasecmp (buff, &theStrings(i,0)))
+    {
+#if defined(_MSC_VER) && _MSC_VER < 1900
+      // MSVC < 2015 prints nan and inf as 1.#NAN or 1.INF, and noes not recognize nan or inf on read
+      if (strstr (aStr, "1.#") || strstr (aStr, "nan") || strstr (aStr, "inf") || 
+          strstr (aStr, "NAN") || strstr (aStr, "INF"))
+        continue;
+#endif
+      if (aNbErr < 5)
+      {
+        di << "Deviation parsing " << aStr << " and print back: " << buff << "\n";
+      }
+      aNbErr++;
+    }
+  }
+  return aNbErr;
+}
+
+// Test speed of standard and OCCT-specific (accelerated) functions to parse string to double
+static Standard_Integer QATestAtof (Draw_Interpretor& di, Standard_Integer argc, const char ** argv)
+{
+  int aNbToTest = Max (100, (argc > 1 ? Draw::Atoi(argv[1]) : 1000000));
+  int aNbDigits = (argc > 2 ? Draw::Atoi(argv[2]) : 10);
+  double aRangeMin = (argc > 3 ? Draw::Atof(argv[3]) : -1e9);
+  double aRangeMax = (argc > 4 ? Draw::Atof(argv[4]) : 1e9);
+
+  char aFormat[256];
+  Sprintf (aFormat, "%%.%dlg", Max (2, Min (20, aNbDigits)));
+
+  // prepare data
+  const int MAXLEN = 256;
+  NCollection_Array2<char> aValuesStr (0, aNbToTest - 1, 0, MAXLEN);
+  math_BullardGenerator aRandom;
+
+  if (aRangeMin < aRangeMax)
+  {
+    // random values within specified range
+//    std::default_random_engine aRandomEngine;
+//    std::uniform_real_distribution<double> aRandomDistr (aRangeMin, aRangeMax);
+    const uint64_t aMaxUInt64 = ~(uint64_t)0; // could be (not supported by old GCC): std::numeric_limits<uint64_t>::max()
+    for (int i = 0; i < aNbToTest; i++)
+    {
+//      double aVal = aRandomDistr (aRandomEngine);
+      uint64_t aIVal = ((uint64_t)aRandom.NextInt() << 32) + aRandom.NextInt();
+      double aVal = aRangeMin + (aIVal / (double)aMaxUInt64) * (aRangeMax - aRangeMin);
+      Sprintf(&aValuesStr(i,0), aFormat, aVal);
+    }
+  }
+  else
+  {
+    // special values
+    int i = 0;
+
+    strcpy (&aValuesStr(i++,0), "nan");
+    strcpy (&aValuesStr(i++,0), "nan(qnan)");
+    strcpy (&aValuesStr(i++,0), "NAN");
+    strcpy (&aValuesStr(i++,0), "-nan");
+    strcpy (&aValuesStr(i++,0), "-NAN");
+    strcpy (&aValuesStr(i++,0), "inf");
+    strcpy (&aValuesStr(i++,0), "INF");
+    strcpy (&aValuesStr(i++,0), "-inf");
+    strcpy (&aValuesStr(i++,0), "-INF");
+
+    strcpy (&aValuesStr(i++,0), "  ."); // standalone period should not be considered as a  number
+    strcpy (&aValuesStr(i++,0), "nanabcdef_128  xx"); // extra non-parenthised sequence after "nan"
+
+    strcpy (&aValuesStr(i++,0), "905791934.11394954"); // value that gets rounded in a wrong way by fast Strtod()
+    strcpy (&aValuesStr(i++,0), "9.343962790444495e+148"); // value where strtod() and Strtod() differ by 2 Epsilon
+
+    strcpy (&aValuesStr(i++,0), "     12345.67text"); // test for leading whitespaces and trailing text
+    strcpy (&aValuesStr(i++,0), "000.000"); // test for zero
+    strcpy (&aValuesStr(i++,0), "000.000e-0002"); // test for zero
+
+    strcpy (&aValuesStr(i++,0), "1000000000000000000000000000012345678901234567890"); // huge mantissa
+    strcpy (&aValuesStr(i++,0), "0000000000.00000000000000000012345678901234567890"); // leading zeros
+    strcpy (&aValuesStr(i++,0), "1.00000000000000000000000000012345678901234567890"); // long fractional part
+
+    strcpy (&aValuesStr(i++,0), "0.0000000001e318"); // large exponent but no overflow
+    strcpy (&aValuesStr(i++,0), "-1.7976931348623158e+308"); // -DBL_MAX 
+    strcpy (&aValuesStr(i++,0), "1.79769313486232e+308"); // overflow
+
+    strcpy (&aValuesStr(i++,0), "10000000000e-310"); // large negative exponent but no underflow
+    strcpy (&aValuesStr(i++,0), "1.1e-310"); // underflow
+    strcpy (&aValuesStr(i++,0), "0.000001e-310"); // underflow
+    strcpy (&aValuesStr(i++,0), "2.2250738585072014e-308"); // underflow, DBL_MIN
+    strcpy (&aValuesStr(i++,0), "2.2250738585e-308"); // underflow, value less than DBL_MIN
+
+    strcpy (&aValuesStr(i++,0), "2.2204460492503131e-016"); // DBL_EPSILON
+
+    // random binary data
+//    std::default_random_engine aRandomEngine;
+//    std::uniform_int_distribution<uint64_t> aRandomDistr (0, ~(uint64_t)0);
+    for (; i < aNbToTest; i++)
+    {
+      union {
+        uint64_t valint;
+        double valdbl;
+      } aVal;
+//      aVal.valint = aRandomDistr (aRandomEngine);
+      aVal.valint = ((uint64_t)aRandom.NextInt() << 32) + aRandom.NextInt();
+      Sprintf(&aValuesStr(i,0), aFormat, aVal.valdbl);
+    }
+  }
+
+  // test different methods
+#define TEST_ATOF(method) \
+  OSD_Timer aT_##method; aT_##method.Start(); \
+  double aRes_##method = 0.; \
+  for (int i = 0; i < aNbToTest; i++) { aRes_##method += test_##method (&aValuesStr(i,0)); } \
+  aT_##method.Stop()
+
+  TEST_ATOF(sscanf);
+  TEST_ATOF(strtod);
+  TEST_ATOF(atof);
+  TEST_ATOF(Strtod);
+  TEST_ATOF(Atof);
+#undef TEST_ATOF
+
+  // test different methods
+#define CHECK_ATOF(method) \
+  int aNbErr_##method = check_atof (aValuesStr, aFormat, test_##method, di); \
+  di << "Checking " << #method << ": " << aNbErr_##method << " deviations\n"
+
+  CHECK_ATOF(sscanf);
+  CHECK_ATOF(strtod);
+  CHECK_ATOF(atof);
+  CHECK_ATOF(Strtod);
+  CHECK_ATOF(Atof);
+#undef CHECK_ATOF
+
+/* compare results with atof */
+#ifdef _MSC_VER
+#define ISFINITE _finite
+#else
+#define ISFINITE std::isfinite
+#endif
+  int nbErr = 0;
+  for (int i = 0; i < aNbToTest; i++)
+  {
+    char *aStr = &aValuesStr(i,0), *anEndOCCT, *anEndStd;
+    double aRes = Strtod (aStr, &anEndOCCT);
+    double aRef = strtod (aStr, &anEndStd);
+    if (ISFINITE(aRes) != ISFINITE(aRef))
+    {
+      nbErr++;
+#if defined(_MSC_VER) && _MSC_VER < 1900
+      // MSVC < 2015 prints nan and inf as 1.#NAN or 1.INF, and noes not recognize nan or inf on read
+      if (strstr (aStr, "1.#") || strstr (aStr, "nan") || strstr (aStr, "inf") || 
+          strstr (aStr, "NAN") || strstr (aStr, "INF"))
+        continue;
+#endif
+      if (nbErr < 5)
+      {
+        char aBuff[256];
+        Sprintf (aBuff, "Error parsing %s: %.20lg / %.20lg\n", aStr, aRes, aRef);
+        di << aBuff;
+      }
+    }
+    else if (ISFINITE(aRef) && Abs (aRes - aRef) > Epsilon (aRef))
+    {
+      nbErr++;
+      if (nbErr < 5)
+      {
+        char aBuff[256];
+        Sprintf (aBuff, "Error parsing %s: %.20lg / %.20lg\n", aStr, aRes, aRef);
+        di << aBuff;
+        Sprintf (aBuff, "[Delta = %.8lg, Epsilon = %.8lg]\n", Abs (aRes - aRef), Epsilon (aRef));
+        di << aBuff;
+      }
+    }
+
+    // check that Strtod() and strtod() stop at the same place;
+    // this makes sense for reading special values such as "nan" and thus
+    // is not relevant for MSVC 2010 and earlier than do not support these
+#if ! defined(_MSC_VER) || _MSC_VER >= 1700
+    if (anEndOCCT != anEndStd)
+    {
+      nbErr++;
+      if (nbErr < 5)
+        di << "Error: different number of symbols parsed in " 
+           << aStr << ": " << (int)(anEndOCCT - aStr) << " / " << (int)(anEndStd - aStr) << "\n";
+    }
+#endif
+  }
+  di << "Total " << nbErr << " defiations from strtod() found\n"; 
+/* */
+
+  // print results
+  di << "Method\t      CPU\t  Elapsed   \t    Deviations \tChecksum\n";
+
+#define PRINT_RES(method) \
+  di << #method "\t" << aT_##method.UserTimeCPU() << "  \t" << aT_##method.ElapsedTime() << "\t" \
+  << aNbErr_##method << "\t" << aRes_##method << "\n"
+  PRINT_RES(sscanf);
+  PRINT_RES(strtod);
+  PRINT_RES(atof);
+  PRINT_RES(Strtod);
+  PRINT_RES(Atof);
+#undef PRINT_RES
+
+  return 0;
+}
+
 void QANCollection::CommandsTest(Draw_Interpretor& theCommands) {
   const char *group = "QANCollection";
 
@@ -877,5 +1123,6 @@ void QANCollection::CommandsTest(Draw_Interpretor& theCommands) {
   theCommands.Add("QANColTestList",           "QANColTestList",           __FILE__, QANColTestList,           group);  
   theCommands.Add("QANColTestSequence",       "QANColTestSequence",       __FILE__, QANColTestSequence,       group);  
   theCommands.Add("QANColTestVector",         "QANColTestVector",         __FILE__, QANColTestVector,         group);  
-  theCommands.Add("QANColTestArrayMove",      "QANColTestArrayMove (is expected to give error)",      __FILE__, QANColTestArrayMove,      group);  
+  theCommands.Add("QANColTestArrayMove",      "QANColTestArrayMove (is expected to give error)", __FILE__, QANColTestArrayMove, group);  
+  theCommands.Add("QATestAtof", "QATestAtof [nbvalues [nbdigits [min [max]]]]", __FILE__, QATestAtof, group);
 }
index 29f669f..cb49a57 100644 (file)
@@ -235,6 +235,23 @@ static inline bool str_starts_with (const char* theStr, const char* theWord, int
   return !strncmp (theStr, theWord, theN);
 }
 
+static bool ReadVertex (const char* theStr, double& theX, double& theY, double& theZ)
+{
+  const char *aStr = theStr;
+
+  // skip 'vertex'
+  while (isspace ((unsigned char)*aStr) || isalpha ((unsigned char)*aStr)) 
+    ++aStr;
+
+  // read values
+  char *aEnd;
+  theX = Strtod (aStr, &aEnd);
+  theY = Strtod (aStr = aEnd, &aEnd);
+  theZ = Strtod (aStr = aEnd, &aEnd);
+
+  return aEnd != aStr;
+}
+
 //==============================================================================
 //function : ReadAscii
 //purpose  :
@@ -314,11 +331,9 @@ Standard_Boolean RWStl_Reader::ReadAscii (Standard_IStream& theStream,
     aNbLine += 5;
 
     Standard_Real x1, y1, z1, x2, y2, z2, x3, y3, z3;
-    Standard_Integer aReadCount = // read 3 lines "vertex x y z"
-      sscanf_l (aLine1, aLocale, "%*s %lf %lf %lf", &x1, &y1, &z1) +
-      sscanf_l (aLine2, aLocale, "%*s %lf %lf %lf", &x2, &y2, &z2) +
-      sscanf_l (aLine3, aLocale, "%*s %lf %lf %lf", &x3, &y3, &z3);
-    if (aReadCount != 9)
+    if (! ReadVertex (aLine1, x1, y1, z1) ||
+        ! ReadVertex (aLine2, x2, y2, z2) ||
+        ! ReadVertex (aLine3, x3, y3, z3))
     {
       TCollection_AsciiString aStr ("Error: cannot read vertex co-ordinates at line ");
       aStr += aNbLine;
index da33f5a..a8c48a1 100755 (executable)
@@ -79,9 +79,9 @@ Standard_Real.hxx
 Standard_ShortReal.cxx
 Standard_ShortReal.hxx
 Standard_Size.hxx
-Standard_SStream.cxx
 Standard_SStream.hxx
 Standard_Stream.hxx
+Standard_Strtod.cxx
 Standard_ThreadId.hxx
 Standard_Time.hxx
 Standard_TooManyUsers.hxx
@@ -92,7 +92,6 @@ Standard_Type.hxx
 Standard_TypeDef.hxx
 Standard_TypeMismatch.hxx
 Standard_Underflow.hxx
-Standard_UUID.cxx
 Standard_UUID.hxx
 Standard_values.h
 Standard_Version.hxx
index d10974f..9e05938 100755 (executable)
@@ -90,10 +90,12 @@ Standard_Integer HashCodes (const Standard_CString Value,
   #define vfprintf_l(theFile,   theLocale, theFormat, theArgPtr) vfprintf(theFile,   theFormat, theArgPtr)
 #endif
 
+/*
 double Strtod (const char* theStr, char** theNextPtr)
 {
   return strtod_l (theStr, theNextPtr, Standard_CLocaleSentry::GetCLocale());
 }
+*/
 
 double Atof (const char* theStr)
 {
index f28414f..798e346 100644 (file)
 #ifndef _Standard_CString_HeaderFile
 # define _Standard_CString_HeaderFile
 
-# ifndef _Standard_TypeDef_HeaderFile
-#  include <Standard_TypeDef.hxx>
-# endif
+#include <Standard_Macro.hxx>
+
+# include <string.h>
+# include <stdio.h>
 
 # if defined(_MSC_VER) && ! defined(strcasecmp)
 #  define strcasecmp _stricmp
 # endif
 
-# include <string.h>
-# include <stdio.h>
+// C++ only definitions
+#ifdef __cplusplus
 
-# ifndef _Standard_Integer_HeaderFile
-#  include <Standard_Integer.hxx>
-# endif
+#include <Standard_Integer.hxx>
+
+//! Returns bounded hash code for a null-terminated string, in range [1, theUpper]
+__Standard_API Standard_Integer HashCode (const Standard_CString theStr, const Standard_Integer theUpper);
 
-__Standard_API Standard_Integer HashCode (const Standard_CString,
-                           const Standard_Integer);
-inline Standard_Integer HashCode (const Standard_CString,
-                                  const Standard_Integer,
-                                  const Standard_Integer);
-inline Standard_Integer HashCode (const Standard_CString,
-                                  const Standard_Integer ,
-                                  const Standard_Integer ,
-                                  Standard_Integer& );
-__Standard_API Standard_Integer HashCodes (const Standard_CString,
-                                           const Standard_Integer);
-
-//! Equivalents of functions from standard C library that use always C locale
-__Standard_API double Atof    (const char* theStr);
-__Standard_API double Strtod  (const char* theStr, char** theNextPtr);
-__Standard_API int    Printf  (const char* theFormat, ...);
-__Standard_API int    Fprintf (FILE* theFile, const char* theFormat, ...);
-__Standard_API int    Sprintf (char* theBuffer, const char* theFormat, ...);
-
-//============================================================================
-//==== IsEqual : Returns Standard_True if two booleans have the same value
-//============================================================================
-inline Standard_Boolean IsEqual(const Standard_CString One
-                                ,const Standard_CString Two)
+//! Returns 32-bit hash code for the first theLen characters in the string theStr 
+__Standard_API Standard_Integer HashCodes (const Standard_CString theStr, const Standard_Integer theLen);
+
+//! Returns bounded hash code for the first theLen characters in 
+//! the string theStr, in range [1, theUpper]
+inline Standard_Integer HashCode (const Standard_CString theStr,
+                                  const Standard_Integer theLen,
+                                  const Standard_Integer theUpper)
 {
-  return (strcmp(One,Two) == 0);
+//  return (Abs( HashCodes( Value , Len ) ) % Upper ) + 1 ;
+  return HashCode (HashCodes (theStr, theLen), theUpper);
 }
 
-//============================================================================
-//==== HashCode of CString. Returns the HashCode itself and
-//====                              the HashCode % Upper
-//============================================================================
-inline Standard_Integer HashCode (const Standard_CString Value,
-                                  const Standard_Integer Len ,
-                                 const Standard_Integer Upper ,
-                                  Standard_Integer& aHashCode )
+//! Returns Standard_True if two strings are equal
+inline Standard_Boolean IsEqual (const Standard_CString theOne, const Standard_CString theTwo)
 {
-  aHashCode = HashCodes( Value , Len );
-//  return (Abs( aHashCode ) % Upper ) + 1 ;
-  return HashCode( (Standard_Integer)aHashCode , Upper ) ;
+  return strcmp (theOne, theTwo) == 0;
 }
 
-//============================================================================
-//==== HashCode of CString. Returns the HashCode itself and
-//====                              the HashCode % Upper
-//============================================================================
-inline Standard_Integer HashCode (const Standard_CString Value,
-                                  const Standard_Integer Len ,
-                                 const Standard_Integer Upper )
-{
-//  return (Abs( HashCodes( Value , Len ) ) % Upper ) + 1 ;
-  return HashCode( (Standard_Integer) HashCodes( Value , Len ) , Upper ) ;
+#endif /* __cplusplus */
+
+#ifdef __cplusplus
+extern "C" {
+#endif /* __cplusplus */
+
+//! Equivalent of standard C function atof() that always uses C locale
+__Standard_API double Atof (const char* theStr);
+
+//! Optimized equivalent of standard C function strtod() that always uses C locale
+__Standard_API double Strtod (const char* theStr, char** theNextPtr);
+
+//! Equivalent of standard C function printf() that always uses C locale
+__Standard_API int Printf (const char* theFormat, ...);
+
+//! Equivalent of standard C function fprintf() that always uses C locale
+__Standard_API int Fprintf (FILE* theFile, const char* theFormat, ...);
+
+//! Equivalent of standard C function sprintf() that always uses C locale
+__Standard_API int Sprintf (char* theBuffer, const char* theFormat, ...);
+
+#ifdef __cplusplus
 }
+#endif /* __cplusplus */
 
 #endif
index 459a60d..7896d41 100644 (file)
@@ -271,18 +271,24 @@ Standard_GUID::Standard_GUID(const Standard_GUID& aGuid)
         my8b5  = aGuid.my8b5;
         my8b6  = aGuid.my8b6;
 }
-Standard_GUID::Standard_GUID(const Standard_UUID& aWntGuid)
+
+Standard_GUID::Standard_GUID (const Standard_UUID& theUUID)
+{
+  Assign (theUUID);
+}
+
+void Standard_GUID::Assign (const Standard_UUID& theUUID) 
 {
-        my32b  = aWntGuid.Data1;
-        my16b1 = aWntGuid.Data2;
-        my16b2 = aWntGuid.Data3;
-        my16b3 = (aWntGuid.Data4[0] << 8) | (aWntGuid.Data4[1]) ;
-        my8b1  = aWntGuid.Data4[2] ;
-        my8b2  = aWntGuid.Data4[3] ;
-        my8b3  = aWntGuid.Data4[4] ;
-        my8b4  = aWntGuid.Data4[5] ;
-        my8b5  = aWntGuid.Data4[6] ;
-        my8b6  = aWntGuid.Data4[7] ;
+  my32b  = theUUID.Data1;
+  my16b1 = theUUID.Data2;
+  my16b2 = theUUID.Data3;
+  my16b3 = (theUUID.Data4[0] << 8) | (theUUID.Data4[1]);
+  my8b1  = theUUID.Data4[2];
+  my8b2  = theUUID.Data4[3];
+  my8b3  = theUUID.Data4[4];
+  my8b4  = theUUID.Data4[5];
+  my8b5  = theUUID.Data4[6];
+  my8b6  = theUUID.Data4[7];
 }
 
 //=======================================================================
diff --git a/src/Standard/Standard_SStream.cxx b/src/Standard/Standard_SStream.cxx
deleted file mode 100644 (file)
index df42f61..0000000
+++ /dev/null
@@ -1,13 +0,0 @@
-// Copyright (c) 1998-1999 Matra Datavision
-// Copyright (c) 1999-2014 OPEN CASCADE SAS
-//
-// This file is part of Open CASCADE Technology software library.
-//
-// This library is free software; you can redistribute it and/or modify it under
-// the terms of the GNU Lesser General Public License version 2.1 as published
-// by the Free Software Foundation, with special exception defined in the file
-// OCCT_LGPL_EXCEPTION.txt. Consult the file LICENSE_LGPL_21.txt included in OCCT
-// distribution for complete text of the license and disclaimer of any warranty.
-//
-// Alternatively, this file may be used under the terms of Open CASCADE
-// commercial license or contractual agreement.
index a2f9df7..002ee68 100644 (file)
  *
  ***************************************************************/
 
+/*
+ This code has been downloaded from  http://www.netlib.org/fp/ on 2017-12-16 
+ and adapted for use within Open CASCADE Technology as follows:
+
+ 1. Macro IEEE_8087 is defined unconditionally
+ 2. Forward declarations of strtod() and atof(), and 'extern C' statements are commented out
+ 3. strtod() is renamed to Strtod() (OCCT signature)
+ 4. dtoa(), freedtoa() and supporting functions are disabled (see DISABLE_DTOA)
+ 5. Compiler warnings are suppressed
+
+*/
+
+#include <Standard_CString.hxx>
+
+#define IEEE_8087 1
+#define DISABLE_DTOA
+
+#ifdef _MSC_VER
+#pragma warning(disable: 4706 4244 4127 4334)
+#endif
+
 /* Please send bug reports to David M. Gay (dmg at acm dot org,
  * with " at " changed at "@" and " dot " changed to ".").     */
 
@@ -339,7 +360,7 @@ static double private_mem[PRIVATE_mem], *pmem_next = private_mem;
 #endif
 
 #ifdef __cplusplus
-extern "C" {
+//extern "C" {
 #endif
 
 #if defined(IEEE_8087) + defined(IEEE_MC68k) + defined(VAX) + defined(IBM) != 1
@@ -1051,7 +1072,39 @@ typedef struct BF96 {            /* Normalized 96-bit software floating point numbers */
        { 0xfcf62c1d, 0xee382c42, 0x46729e03, 1073 },
        { 0x9e19db92, 0xb4e31ba9, 0x6c07a2c2, 1077 }
        };
- static short int Lhint[2098] = {
+static ULLong pfive[27] = {
+               5ll,
+               25ll,
+               125ll,
+               625ll,
+               3125ll,
+               15625ll,
+               78125ll,
+               390625ll,
+               1953125ll,
+               9765625ll,
+               48828125ll,
+               244140625ll,
+               1220703125ll,
+               6103515625ll,
+               30517578125ll,
+               152587890625ll,
+               762939453125ll,
+               3814697265625ll,
+               19073486328125ll,
+               95367431640625ll,
+               476837158203125ll,
+               2384185791015625ll,
+               11920928955078125ll,
+               59604644775390625ll,
+               298023223876953125ll,
+               1490116119384765625ll,
+               7450580596923828125ll
+               };
+
+#ifndef DISABLE_DTOA
+static short int Lhint[2098] = {
           /*18,*/19,    19,    19,    19,    20,    20,    20,    21,    21,
           21,    22,    22,    22,    23,    23,    23,    23,    24,    24,
           24,    25,    25,    25,    26,    26,    26,    26,    27,    27,
@@ -1262,38 +1315,11 @@ typedef struct BF96 {           /* Normalized 96-bit software floating point numbers */
          641,   642,   642,   642,   643,   643,   643,   644,   644,   644,
          644,   645,   645,   645,   646,   646,   646,   647,   647,   647,
          647,   648,   648,   648,   649,   649,   649,   650,   650 };
- static ULLong pfive[27] = {
-               5ll,
-               25ll,
-               125ll,
-               625ll,
-               3125ll,
-               15625ll,
-               78125ll,
-               390625ll,
-               1953125ll,
-               9765625ll,
-               48828125ll,
-               244140625ll,
-               1220703125ll,
-               6103515625ll,
-               30517578125ll,
-               152587890625ll,
-               762939453125ll,
-               3814697265625ll,
-               19073486328125ll,
-               95367431640625ll,
-               476837158203125ll,
-               2384185791015625ll,
-               11920928955078125ll,
-               59604644775390625ll,
-               298023223876953125ll,
-               1490116119384765625ll,
-               7450580596923828125ll
-               };
 
  static int pfivebits[25] = {3, 5, 7, 10, 12, 14, 17, 19, 21, 24, 26, 28, 31,
                             33, 35, 38, 40, 42, 45, 47, 49, 52, 54, 56, 59};
+#endif
+
 #endif /*}*/
 #endif /*}} NO_LONG_LONG */
 
@@ -1502,9 +1528,9 @@ static unsigned int maxthreads = 0;
 #define Kmax 7
 
 #ifdef __cplusplus
-extern "C" double strtod(const char *s00, char **se);
-extern "C" char *dtoa(double d, int mode, int ndigits,
-                       int *decpt, int *sign, char **rve);
+//extern "C" double strtod(const char *s00, char **se);
+//extern "C" char *dtoa(double d, int mode, int ndigits,
+//                     int *decpt, int *sign, char **rve);
 #endif
 
  struct
@@ -1597,7 +1623,7 @@ Balloc(int k MTd)
 #else
                len = (sizeof(Bigint) + (x-1)*sizeof(ULong) + sizeof(double) - 1)
                        /sizeof(double);
-               if (k <= Kmax && pmem_next - private_mem + len <= PRIVATE_mem
+               if (k <= Kmax && (unsigned long)(pmem_next - private_mem) + len <= PRIVATE_mem
 #ifdef MULTIPLE_THREADS
                        && TI == TI1
 #endif
@@ -2822,6 +2848,7 @@ gethex( const char **sp, U *rvp, int rounding, int sign MTd)
                  case '-':
                        esign = 1;
                        /* no break */
+                        Standard_FALLTHROUGH
                  case '+':
                        s++;
                  }
@@ -3229,7 +3256,7 @@ sulp(U *x, BCinfo *bc)
 bigcomp(U *rv, const char *s0, BCinfo *bc MTd)
 {
        Bigint *b, *d;
-       int b2, bbits, d2, dd, dig, dsign, i, j, nd, nd0, p2, p5, speccase;
+       int b2, bbits, d2, dd=0, dig, dsign, i, j, nd, nd0, p2, p5, speccase;
 
        dsign = bc->dsign;
        nd = bc->nd;
@@ -3429,7 +3456,7 @@ retlow1:
 #endif /* NO_STRTOD_BIGCOMP */
 
  double
-strtod(const char *s00, char **se)
+Strtod(const char *s00, char **se)
 {
        int bb2, bb5, bbe, bd2, bd5, bbbits, bs2, c, e, e1;
        int esign, i, j, k, nd, nd0, nf, nz, nz0, nz1, sign;
@@ -3439,7 +3466,7 @@ strtod(const char *s00, char **se)
        U aadj2, adj, rv, rv0;
        ULong y, z;
        BCinfo bc;
-       Bigint *bb, *bb1, *bd, *bd0, *bs, *delta;
+       Bigint *bb=0, *bb1=0, *bd=0, *bd0=0, *bs=0, *delta=0;
 #ifdef USE_BF96
        ULLong bhi, blo, brv, t00, t01, t02, t10, t11, terv, tg, tlo, yz;
        const BF96 *p10;
@@ -3479,10 +3506,12 @@ strtod(const char *s00, char **se)
                case '-':
                        sign = 1;
                        /* no break */
+                        Standard_FALLTHROUGH
                case '+':
                        if (*++s)
                                goto break2;
                        /* no break */
+                        Standard_FALLTHROUGH
                case 0:
                        goto ret0;
                case '\t':
@@ -3609,6 +3638,7 @@ strtod(const char *s00, char **se)
                switch(c = *++s) {
                        case '-':
                                esign = 1;
+                                Standard_FALLTHROUGH
                        case '+':
                                c = *++s;
                        }
@@ -4850,6 +4880,9 @@ strtod(const char *s00, char **se)
        return sign ? -dval(&rv) : dval(&rv);
        }
 
+// disable dtoa() and related functions 
+#ifndef DISABLE_DTOA
+
 #ifndef MULTIPLE_THREADS
  static char *dtoa_result;
 #endif
@@ -6196,8 +6229,10 @@ dtoa(double dd, int mode, int ndigits, int *decpt, int *sign, char **rve)
                freedtoa(dtoa_result);
 #endif
        return dtoa_r(dd, mode, ndigits, decpt, sign, rve, 0, 0);
-       }
+ }
+
+#endif /* DISABLE_DTOA */
 
 #ifdef __cplusplus
-}
+//}
 #endif
diff --git a/src/Standard/Standard_UUID.cxx b/src/Standard/Standard_UUID.cxx
deleted file mode 100644 (file)
index 8e6a12c..0000000
+++ /dev/null
@@ -1,21 +0,0 @@
-// Copyright (c) 1998-1999 Matra Datavision
-// Copyright (c) 1999-2014 OPEN CASCADE SAS
-//
-// This file is part of Open CASCADE Technology software library.
-//
-// This library is free software; you can redistribute it and/or modify it under
-// the terms of the GNU Lesser General Public License version 2.1 as published
-// by the Free Software Foundation, with special exception defined in the file
-// OCCT_LGPL_EXCEPTION.txt. Consult the file LICENSE_LGPL_21.txt included in OCCT
-// distribution for complete text of the license and disclaimer of any warranty.
-//
-// Alternatively, this file may be used under the terms of Open CASCADE
-// commercial license or contractual agreement.
-
-#include <Standard_GUID.hxx>
-#include <Standard_UUID.hxx>
-
-//void Standard_GUID::Assign(const Standard_UUID& uid) 
-void Standard_GUID::Assign(const Standard_UUID& ) 
-{
-}
index c94a878..0241b63 100644 (file)
@@ -8,7 +8,7 @@ set ref_data {
 DATA        : Faulties = 0  ( 0 )  Warnings = 0  ( 0 )  Summary  = 0  ( 0 )
 TPSTAT      : Faulties = 0  ( 0 )  Warnings = 42  ( 58 )  Summary  = 42  ( 58 )
 CHECKSHAPE  : Wires    = 0  ( 0 )  Faces    = 0  ( 0 )  Shells   = 0  ( 0 )   Solids   = 0 ( 0 )
-NBSHAPES    : Solid    = 0  ( 0 )  Shell    = 49  ( 0 )  Face     = 49  ( 49 )   Summary  = 579  ( 529 )
+NBSHAPES    : Solid    = 0  ( 0 )  Shell    = 49  ( 0 )  Face     = 49  ( 49 )   Summary  = 579  ( 530 )
 STATSHAPE   : Solid    = 0  ( 0 )  Shell    = 49  ( 0 )  Face     = 49  ( 49 )   FreeWire = 0  ( 0 )   FreeEdge  = 0 ( 0 )   SharedEdge = 220  ( 218 )
 TOLERANCE   : MaxTol   = 0.003591433268  ( 0.006121716429 )  AvgTol   =  0.0002657130942  (  0.0004625449099 )
 LABELS      : N0Labels = 1  ( 1 )  N1Labels = 0  ( 0 )  N2Labels = 0  ( 0 )   TotalLabels = 1  ( 1 )   NameLabels = 1  ( 1 )   ColorLabels = 0  ( 0 )   LayerLabels = 0  ( 0 )
index 2611c72..cc25fb9 100755 (executable)
@@ -7,9 +7,9 @@ set filename Z8M6SAT.stp
 set ref_data {
 DATA        : Faulties = 0  ( 0 )  Warnings = 0  ( 0 )  Summary  = 0  ( 0 )
 TPSTAT      : Faulties = 0  ( 0 )  Warnings = 940  ( 3170 )  Summary  = 940  ( 3170 )
-CHECKSHAPE  : Wires    = 49  ( 43 )  Faces    = 50  ( 49 )  Shells   = 0  ( 2 )   Solids   = 0 ( 0 )
-NBSHAPES    : Solid    = 28  ( 28 )  Shell    = 768  ( 30 )  Face     = 3240  ( 3239 )   Summary  = 29365  ( 28618 )
-STATSHAPE   : Solid    = 28  ( 28 )  Shell    = 768  ( 30 )  Face     = 3240  ( 3239 )   FreeWire = 0  ( 0 )   FreeEdge  = 0 ( 0 )   SharedEdge = 12581  ( 12573 )
+CHECKSHAPE  : Wires    = 45  ( 44 )  Faces    = 46  ( 42 )  Shells   = 0  ( 2 )   Solids   = 0 ( 0 )
+NBSHAPES    : Solid    = 28  ( 28 )  Shell    = 768  ( 30 )  Face     = 3240  ( 3239 )   Summary  = 29368  ( 28620 )
+STATSHAPE   : Solid    = 28  ( 28 )  Shell    = 768  ( 30 )  Face     = 3240  ( 3239 )   FreeWire = 0  ( 0 )   FreeEdge  = 0 ( 0 )   SharedEdge = 12582  ( 12573 )
 TOLERANCE   : MaxTol   =    15.00300076  (    20.46526799 )  AvgTol   =   0.02248945623  (   0.03724082116 )
 LABELS      : N0Labels = 3  ( 3 )  N1Labels = 2  ( 2 )  N2Labels = 0  ( 0 )   TotalLabels = 5  ( 5 )   NameLabels = 5  ( 5 )   ColorLabels = 0  ( 0 )   LayerLabels = 0  ( 0 )
 PROPS       : Centroid = 0  ( 0 )  Volume   = 0  ( 0 )  Area     = 0  ( 0 )
diff --git a/tests/perf/draw/restore b/tests/perf/draw/restore
new file mode 100644 (file)
index 0000000..9cd505c
--- /dev/null
@@ -0,0 +1,11 @@
+puts "# ======================================================================"
+puts "# 0029399: Optimize reading of floating point values from text strings "
+puts "# ======================================================================"
+puts ""
+puts "# Test to monitor performance of reading large BREP file"
+
+set file [locate_data_file OCC54.brep]
+
+dchrono s restart
+restore $file a
+dchrono s stop counter "restore"
diff --git a/tests/perf/fclasses/strtod b/tests/perf/fclasses/strtod
new file mode 100644 (file)
index 0000000..aa4c254
--- /dev/null
@@ -0,0 +1,48 @@
+puts "================================================================="
+puts "Testing performance of Strtod() vs. standard strtod()"
+puts "================================================================="
+puts ""
+
+pload QAcommands
+
+# Check that performance of Strtod() and Atof() is at least twice better 
+# than that of standard strtod() and atof()
+proc CheckAtof {nbvalues nbdigits min max} {
+  set res [QATestAtof $nbvalues $nbdigits $min $max]
+#  puts $res
+
+  if { ! [regexp {atof\s+([0-9.]+)} $res bidon cpu_atof] ||
+       ! [regexp {Atof\s+([0-9.]+)} $res bidon cpu_Atof] ||
+       ! [regexp {strtod\s+([0-9.]+)} $res bidon cpu_strtod] ||
+       ! [regexp {Strtod\s+([0-9.]+)} $res bidon cpu_Strtod] } {
+    puts "Error: cannot interpret results of test command!"
+  } else {
+    if { $cpu_atof < 2 * $cpu_Atof } {
+      puts "Error: Atof() is expected to be at least 2 times better than atof()!"
+    }
+    if { $cpu_strtod < 2 * $cpu_Strtod } {
+      puts "Error: Strtod() is expected to be at least 2 times better than strtod()!"
+    }
+  }
+}
+
+puts "1M random values, 10 significant digits, in range (-1e9, 1e9)"
+CheckAtof 1000000 10 -1e9 1e9
+
+puts "1M random values, 10 significant digits, in range (-1e305, 1e305)"
+CheckAtof 1000000 10 -1e305 1e305
+
+puts "1M random values, 16 significant digits, in range (-1e9, 1e9)"
+CheckAtof 1000000 16 -1e9 1e9
+
+puts "1M random values, 18 significant digits, in range (-1e305, 1e305)"
+CheckAtof 1000000 16 -1e305 1e305
+
+# Disarm FPE signals - otherwise they will be raised if signaling NAN appears
+dsetsignal 0
+
+puts "Special values + 1M values defined by random binary data, 10 digits"
+CheckAtof 1000000 10 0 0
+
+puts "Special values + 1M values defined by random binary data, 16 digits"
+CheckAtof 1000000 16 0 0