Fix rounding error in GDSII driver.
* Bug: In CRL/GdsStream::toGdsDbu(), when converting a physical number, in double to a number of GDSII dbu in int32_t, we must not use the direct cast int32_t(v) because v can be 2.9999999999 which got simply truncated into 2 while we want 3. So now use the rounding function std::lrint() and configure it round to the *nearest* integer. Note that we don't check that the long returned can correctly fit into int32_t.
This commit is contained in:
parent
acc9405ba3
commit
d05539378c
|
@ -15,6 +15,8 @@
|
||||||
|
|
||||||
|
|
||||||
#include <ctime>
|
#include <ctime>
|
||||||
|
#include <cmath>
|
||||||
|
#include <cfenv>
|
||||||
#include <string>
|
#include <string>
|
||||||
#include <sstream>
|
#include <sstream>
|
||||||
#include <fstream>
|
#include <fstream>
|
||||||
|
@ -377,7 +379,8 @@ namespace {
|
||||||
inline GdsRecord GdsStream::LIBNAME ( string s ) { return GdsRecord(GdsRecord::LIBNAME,s); }
|
inline GdsRecord GdsStream::LIBNAME ( string s ) { return GdsRecord(GdsRecord::LIBNAME,s); }
|
||||||
inline GdsRecord GdsStream::SNAME ( string s ) { return GdsRecord(GdsRecord::SNAME,s); }
|
inline GdsRecord GdsStream::SNAME ( string s ) { return GdsRecord(GdsRecord::SNAME,s); }
|
||||||
inline GdsRecord GdsStream::SNAME ( const Name& n ) { return GdsRecord(GdsRecord::SNAME,getString(n)); }
|
inline GdsRecord GdsStream::SNAME ( const Name& n ) { return GdsRecord(GdsRecord::SNAME,getString(n)); }
|
||||||
inline int32_t GdsStream::toGdsDbu ( DbU::Unit v ) const { return DbU::toPhysical( v, DbU::UnitPower::Unity ) / _metricDbU; }
|
inline int32_t GdsStream::toGdsDbu ( DbU::Unit v ) const
|
||||||
|
{ return uint32_t( std::lrint( DbU::toPhysical( v, DbU::UnitPower::Unity ) / _metricDbU )); }
|
||||||
|
|
||||||
|
|
||||||
GdsStream::GdsStream ( string filename )
|
GdsStream::GdsStream ( string filename )
|
||||||
|
@ -385,6 +388,7 @@ namespace {
|
||||||
, _dbuPerUu (Cfg::getParamDouble("gdsDriver.dbuPerUu" ,0.001)->asDouble()) // 1000
|
, _dbuPerUu (Cfg::getParamDouble("gdsDriver.dbuPerUu" ,0.001)->asDouble()) // 1000
|
||||||
, _metricDbU(Cfg::getParamDouble("gdsDriver.metricDbu",10e-9)->asDouble()) // 1um.
|
, _metricDbU(Cfg::getParamDouble("gdsDriver.metricDbu",10e-9)->asDouble()) // 1um.
|
||||||
{
|
{
|
||||||
|
std::fesetround( FE_TONEAREST );
|
||||||
_ostream.open( filename, ios_base::out );
|
_ostream.open( filename, ios_base::out );
|
||||||
|
|
||||||
GdsRecord record ( GdsRecord::HEADER );
|
GdsRecord record ( GdsRecord::HEADER );
|
||||||
|
|
Loading…
Reference in New Issue