mirror of
https://github.com/Gnucash/gnucash.git
synced 2025-02-25 18:55:30 -06:00
tweak yet another possible overflow path
git-svn-id: svn+ssh://svn.gnucash.org/repo/gnucash/trunk@10138 57a11ea4-9604-0410-9ed3-97b8803252fd
This commit is contained in:
parent
3e14e8c3d3
commit
c1f9d93c9c
@ -421,7 +421,7 @@ gnc_numeric_mul(gnc_numeric a, gnc_numeric b,
|
|||||||
gint64 denom, gint how)
|
gint64 denom, gint how)
|
||||||
{
|
{
|
||||||
gnc_numeric product, result;
|
gnc_numeric product, result;
|
||||||
qofint128 bigprod;
|
qofint128 bignume, bigdeno;
|
||||||
|
|
||||||
if(gnc_numeric_check(a) || gnc_numeric_check(b)) {
|
if(gnc_numeric_check(a) || gnc_numeric_check(b)) {
|
||||||
return gnc_numeric_error(GNC_ERROR_ARG);
|
return gnc_numeric_error(GNC_ERROR_ARG);
|
||||||
@ -453,19 +453,24 @@ gnc_numeric_mul(gnc_numeric a, gnc_numeric b,
|
|||||||
b.denom = 1;
|
b.denom = 1;
|
||||||
}
|
}
|
||||||
|
|
||||||
bigprod = mult128 (a.num, b.num);
|
bignume = mult128 (a.num, b.num);
|
||||||
|
bigdeno = mult128 (a.denom, b.denom);
|
||||||
product.num = a.num*b.num;
|
product.num = a.num*b.num;
|
||||||
product.denom = a.denom*b.denom;
|
product.denom = a.denom*b.denom;
|
||||||
|
|
||||||
/* If it looks to be overflowing, try to reduce the fraction ... */
|
/* If it looks to be overflowing, try to reduce the fraction ... */
|
||||||
if (bigprod.isbig)
|
if (bignume.isbig || bigdeno.isbig)
|
||||||
{
|
{
|
||||||
/* If rounding allowed, then shift until there's no
|
/* If rounding allowed, then shift until there's no
|
||||||
* more overflow. The conversion at the end will fix
|
* more overflow. The conversion at the end will fix
|
||||||
* things up for the final value. */
|
* things up for the final value. Else overflow. */
|
||||||
if ((how & GNC_NUMERIC_RND_MASK) == GNC_HOW_RND_NEVER)
|
if ((how & GNC_NUMERIC_RND_MASK) == GNC_HOW_RND_NEVER)
|
||||||
{
|
{
|
||||||
product = reduce128 (bigprod, product.denom);
|
if (bigdeno.isbig)
|
||||||
|
{
|
||||||
|
return gnc_numeric_error (GNC_ERROR_OVERFLOW);
|
||||||
|
}
|
||||||
|
product = reduce128 (bignume, product.denom);
|
||||||
if (gnc_numeric_check (product))
|
if (gnc_numeric_check (product))
|
||||||
{
|
{
|
||||||
return gnc_numeric_error (GNC_ERROR_OVERFLOW);
|
return gnc_numeric_error (GNC_ERROR_OVERFLOW);
|
||||||
@ -473,13 +478,15 @@ gnc_numeric_mul(gnc_numeric a, gnc_numeric b,
|
|||||||
}
|
}
|
||||||
else
|
else
|
||||||
{
|
{
|
||||||
while (bigprod.isbig)
|
while (bignume.isbig || bigdeno.isbig)
|
||||||
{
|
{
|
||||||
bigprod = shift128 (bigprod);
|
bignume = shift128 (bignume);
|
||||||
product.denom >>= 1;
|
bigdeno = shift128 (bigdeno);
|
||||||
}
|
}
|
||||||
product.num = bigprod.lo;
|
product.num = bignume.lo;
|
||||||
if (bigprod.isneg) product.num = -product.num;
|
if (bignume.isneg) product.num = -product.num;
|
||||||
|
|
||||||
|
product.denom = bigdeno.lo;
|
||||||
if (0 == product.denom)
|
if (0 == product.denom)
|
||||||
{
|
{
|
||||||
return gnc_numeric_error (GNC_ERROR_OVERFLOW);
|
return gnc_numeric_error (GNC_ERROR_OVERFLOW);
|
||||||
|
Loading…
Reference in New Issue
Block a user