Skip to content

Commit

Permalink
Merge pull request #306 from andy-123/fb4datatypesbug
Browse files Browse the repository at this point in the history
Int128 does not respect scale (Issue #166)
  • Loading branch information
mariuz authored Apr 11, 2023
2 parents 0813c1c + 9b6065d commit 29fe037
Show file tree
Hide file tree
Showing 5 changed files with 121 additions and 24 deletions.
57 changes: 46 additions & 11 deletions src/core/FRDecimal.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -482,10 +482,11 @@ wxString Dec34DPDToString(dec34_t value)
return DecInfoToString(CDec34DPDDef, info);
}

// input definition + src
// ouput dstInfo
// input def + srcStr
// ouput dstInfo + errMsg
bool StringToDecParse(const DECFLOAT_DEFINITION& def,
const wxString& srcStr, DECFLOAT_DECINFO* dstInfo)
const wxString& srcStr, DECFLOAT_DECINFO* dstInfo,
wxString& errMsg)
{
wxString valueStr;
wxString expStr;
Expand All @@ -501,7 +502,10 @@ bool StringToDecParse(const DECFLOAT_DEFINITION& def,
*dstInfo = {0};

if (srcStr.IsEmpty())
{
errMsg = _("SrcStr is empty!");
return false;
}

srcStrL = srcStr.Lower();
if (srcStrL == _("nan"))
Expand Down Expand Up @@ -535,7 +539,12 @@ bool StringToDecParse(const DECFLOAT_DEFINITION& def,
{
// more than one dot?
if (DecimalSeparatorPos != -1)
{
errMsg = wxString::Format(
_("Not numeric. Found 2nd decimalseparator (%c) at position %d."),
DecimalSeparator, i1+1);
return false;
}
DecimalSeparatorPos = i1 - iStart;
continue;
}
Expand All @@ -550,7 +559,12 @@ bool StringToDecParse(const DECFLOAT_DEFINITION& def,
}
// not numeric
if ((ch < '0') || (ch > '9'))
{
errMsg = wxString::Format(
_("Not numeric. Invalid char (%c) at position %d."),
ch, i1+1);
return false;
}
valueStr = valueStr + ch;
}
if (iStart < i1)
Expand All @@ -560,7 +574,10 @@ bool StringToDecParse(const DECFLOAT_DEFINITION& def,
{
// exponent expected (e.g becase trailing space like "123 ")
if (NeedExponent)
{
errMsg = "Not numeric. Exponent expected or invalid trailing space.";
return false;
}
expStr = _("0");
}
else
Expand All @@ -584,14 +601,24 @@ bool StringToDecParse(const DECFLOAT_DEFINITION& def,
}
// numeric?
if ((ch < '0') || (ch > '9'))
{
errMsg = wxString::Format(
_("Not numeric. Invalid char (%c) at position %d."),
ch, i1+1);
return false;
}
expStr += ch;
}
}


if (!expStr.ToLong(&tmpVal, 10))
{
errMsg = wxString::Format(
_("Not numeric. Invalid exponent (%c)."),
tmpVal);
return false;
}

// Add decimaldigits to exponent
DecimalDigits = valueStr.Length() - DecimalSeparatorPos;
Expand Down Expand Up @@ -714,7 +741,7 @@ uint16_t Str3ToDeclet(const wxString& str, int& offset)
return declet;
}

bool DecInfoToDec34DPD(const DECFLOAT_DECINFO &info, dec34_t* dst)
bool DecInfoToDec34DPD(const DECFLOAT_DECINFO &info, dec34_t* dst, wxString& errMsg)
{
DECFLOAT128_UNION dfu = {0};
DECFLOAT_DEFINITION def = CDec34DPDDef;
Expand All @@ -739,7 +766,11 @@ bool DecInfoToDec34DPD(const DECFLOAT_DECINFO &info, dec34_t* dst)
// exponent in range?
if ((info.exp < -def.minExp) ||
(info.exp > def.maxExp))
{
errMsg = wxString::Format(
_("Exponent (%d) out of range!"), info.exp);
return false;
}

uint32_t exp = info.exp + def.minExp;

Expand Down Expand Up @@ -778,7 +809,7 @@ bool DecInfoToDec34DPD(const DECFLOAT_DECINFO &info, dec34_t* dst)
return true;
}

bool DecInfoToDec16DPD(const DECFLOAT_DECINFO &info, dec16_t* dst)
bool DecInfoToDec16DPD(const DECFLOAT_DECINFO &info, dec16_t* dst, wxString& errMsg)
{
DECFLOAT64_UNION dfu = {0};
DECFLOAT_DEFINITION def = CDec16DPDDef;
Expand All @@ -803,7 +834,11 @@ bool DecInfoToDec16DPD(const DECFLOAT_DECINFO &info, dec16_t* dst)
// exponent in range?
if ((info.exp < -def.minExp) ||
(info.exp > def.maxExp))
{
errMsg = wxString::Format(
_("Exponent (%d) out of range!"), info.exp);
return false;
}

uint32_t exp = info.exp + def.minExp;

Expand All @@ -830,12 +865,12 @@ bool DecInfoToDec16DPD(const DECFLOAT_DECINFO &info, dec16_t* dst)
return true;
}

bool StringToDec34DPD(const wxString& src, dec34_t* dst)
bool StringToDec34DPD(const wxString& src, dec34_t* dst, wxString& errMsg)
{
DECFLOAT_DECINFO info;
if (!StringToDecParse(CDec34DPDDef, src, &info))
if (!StringToDecParse(CDec34DPDDef, src, &info, errMsg))
return false;
if (!DecInfoToDec34DPD(info, dst))
if (!DecInfoToDec34DPD(info, dst, errMsg))
return false;
return true;
}
Expand All @@ -848,12 +883,12 @@ wxString Dec16DPDToString(dec16_t value)
return DecInfoToString(CDec16DPDDef, info);
}

bool StringToDec16DPD(const wxString& src, dec16_t* dst)
bool StringToDec16DPD(const wxString& src, dec16_t* dst, wxString& errMsg)
{
DECFLOAT_DECINFO info;
if (!StringToDecParse(CDec34DPDDef, src, &info))
if (!StringToDecParse(CDec34DPDDef, src, &info, errMsg))
return false;
if (!DecInfoToDec16DPD(info, dst))
if (!DecInfoToDec16DPD(info, dst, errMsg))
return false;
return true;
}
4 changes: 2 additions & 2 deletions src/core/FRDecimal.h
Original file line number Diff line number Diff line change
Expand Up @@ -31,8 +31,8 @@ typedef IBPP::ibpp_dec16_t dec16_t;
typedef IBPP::ibpp_dec34_t dec34_t;

wxString Dec34DPDToString(dec34_t value);
bool StringToDec34DPD(const wxString& src, dec34_t* dst);
bool StringToDec34DPD(const wxString& src, dec34_t* dst, wxString& errMsg);
wxString Dec16DPDToString(dec16_t value);
bool StringToDec16DPD(const wxString& src, dec16_t* dst);
bool StringToDec16DPD(const wxString& src, dec16_t* dst, wxString& errMsg);

#endif // FR_FRDECIMAL_H
37 changes: 34 additions & 3 deletions src/core/FRInt128.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -31,6 +31,7 @@
#endif

#include "core/FRInt128.h"
#include <wx/numformatter.h>

// enable only for debugging
//#define DEBUG_DDU
Expand Down Expand Up @@ -90,22 +91,43 @@ void DDUdbg(DOUBLE_DABBLE_UNION& ddu)
#define DDUdbg(x)
#endif

bool DDUinitFromStr(DOUBLE_DABBLE_UNION& ddu, bool &isNegative, const wxString &src)
bool DDUinitFromStr(DOUBLE_DABBLE_UNION& ddu, bool &isNegative, const wxString &src, wxString& errMsg)
{
wxString src2;
int i1, iByte;
uint8_t ch;
wxChar sep1000;

isNegative = (src.GetChar(0) == _("-"));
if (isNegative)
src2 = src.Mid(1);
else
src2 = src;

// replace thousand separators - if used
if (wxNumberFormatter::GetThousandsSeparatorIfUsed(&sep1000))
src2.Replace(_(sep1000), _(""));

// Check: numeric?
for (i1 = 0; i1 < src2.Length(); i1++)
{
ch = src2.GetChar(i1);
if ((ch < '0') || (ch > '9'))
{
errMsg = wxString::Format(
_("Not numeric. Invalid char (%c) at position %d."),
ch, i1+1);
return false;
}
}

// Check: number to big?
// Its not really precise but prevents a buffer overflow.
if (src2.Length() > (DOUBLE_DABBLE_BCD_LEN * 2))
{
errMsg = _("Int128: Value to big.");
return false;
}

for (i1 = 0; i1 < src2.Length(); i1++)
{
Expand Down Expand Up @@ -207,15 +229,15 @@ void DDUadd(DOUBLE_DABBLE_UNION& ddu)
}
}

bool StringToInt128(const wxString& src, int128_t* dst)
bool StringToInt128(const wxString& src, int128_t* dst, wxString& errMsg)
{
DOUBLE_DABBLE_UNION ddu = {0};
int i1;
bool isNegative;

// use double dabbl algorithm (reverse)
// initialization
if (!DDUinitFromStr(ddu, isNegative, src))
if (!DDUinitFromStr(ddu, isNegative, src, errMsg))
return false;

for (i1 = 0; i1 < 128; i1++)
Expand All @@ -228,7 +250,10 @@ bool StringToInt128(const wxString& src, int128_t* dst)
// So we have to check if all bits could be moved into the 128-bit
// result.
if (ddu.shift.bcd[DOUBLE_DABBLE_BCD_LEN - 1] != 0)
{
errMsg = _("Int128: Value to big.");
return false;
}

if (isNegative)
{
Expand All @@ -237,13 +262,19 @@ bool StringToInt128(const wxString& src, int128_t* dst)
ddu.shift.lowPart = ddu.shift.lowPart ^ 0xFFFFFFFFFFFFFFFF;
// value to small?
if (ddu.shift.highPart < 0x8000000000000000)
{
errMsg = _("Int128: Value to small.");
return false;
}
}
else
{
// value to big?
if (ddu.shift.highPart >= 0x8000000000000000)
{
errMsg = _("Int128: Value to big.");
return false;
}
}

*dst = ddu.s.i128;
Expand Down
2 changes: 1 addition & 1 deletion src/core/FRInt128.h
Original file line number Diff line number Diff line change
Expand Up @@ -30,6 +30,6 @@
typedef IBPP::ibpp_int128_t int128_t;

wxString Int128ToString(int128_t value);
bool StringToInt128(const wxString& src, int128_t* dst);
bool StringToInt128(const wxString& src, int128_t* dst, wxString& errMsg);

#endif // FR_FRINT128_H
45 changes: 38 additions & 7 deletions src/gui/controls/DataGridRows.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -725,10 +725,39 @@ void Int128ColumnDef::setFromString(DataGridRowBuffer* buffer,
const wxString& source)
{
wxASSERT(buffer);

int128_t v128 = 0;
if (!StringToInt128(source, &v128))
throw FRError(_("Invalid int128 numeric value"));
int i1, decimalSeparatorIdx, localSourceScale;
wxString errMsg;
wxString localSource = source;
wxChar ch;
wxChar decimalSeparator;

if (scaleM > 0)
{
decimalSeparator = wxNumberFormatter::GetDecimalSeparator();
decimalSeparatorIdx = localSource.rfind(decimalSeparator);

if (decimalSeparatorIdx > -1)
{
localSource.erase(decimalSeparatorIdx,1);
localSourceScale = localSource.Length() - decimalSeparatorIdx;
}
else
localSourceScale = 0;

// remove numbers if we are to big
if (localSourceScale > scaleM)
localSource.erase(localSource.Length() - localSourceScale + scaleM);
// add 0 if we are to small
while (localSourceScale < scaleM)
{
localSource = localSource + _("0");
localSourceScale++;
}
}

if (!StringToInt128(localSource, &v128, errMsg))
throw FRError(errMsg);
buffer->setValue(offsetM, v128);
}

Expand Down Expand Up @@ -1349,8 +1378,9 @@ void Dec16ColumnDef::setFromString(DataGridRowBuffer* buffer,
{
wxASSERT(buffer);
dec16_t value;
if (!StringToDec16DPD(source, &value))
throw FRError(_("Invalid decimal34 numeric value"));
wxString errMsg;
if (!StringToDec16DPD(source, &value, errMsg))
throw FRError(errMsg);
buffer->setValue(offsetM, value);
}

Expand Down Expand Up @@ -1410,8 +1440,9 @@ void Dec34ColumnDef::setFromString(DataGridRowBuffer* buffer,
{
wxASSERT(buffer);
dec34_t value;
if (!StringToDec34DPD(source, &value))
throw FRError(_("Invalid decimal34 numeric value"));
wxString errMsg;
if (!StringToDec34DPD(source, &value, errMsg))
throw FRError(errMsg);
buffer->setValue(offsetM, value);
}

Expand Down

0 comments on commit 29fe037

Please sign in to comment.