[Tarantool-patches] [PATCH 1/1] tuple: don't truncate float in :update()

Vladislav Shpilevoy v.shpilevoy at tarantool.org
Tue Jan 28 00:56:23 MSK 2020


Ok, then discard this patch.

On 26/01/2020 19:45, Nikita Pettik wrote:
> On 26 Jan 17:44, Vladislav Shpilevoy wrote:
>> Before the patch there were the rules:
>> * float +/- double = double
>> * double +/- double = double
>> * float +/- float = float
>>
>> The rules were applied regardless of values. That led to a problem
>> when float + float exceeding maximal float value could fit into
>> double, but was stored as an infinity.
>>
>> The patch makes so that if a floating point arithmetic operation
>> result fits into float, it is stored as float. Otherwise as
>> double. Regardless of initial types.
>>
>> This alongside saves some memory for cases when doubles can be
>> stored as floats, and therefore takes 4 less bytes. Although
>> these cases are rare, because any not integer value stored in a
>> double may have a long garbage tail in its fraction.
>>
>> Closes #4701
>> ---
>> Branch: https://github.com/tarantool/tarantool/tree/gerold103/gh-4701-update-float-truncate
>> Issue: https://github.com/tarantool/tarantool/issues/4701
>>
>> I am not sure about the patch correctness. Perhaps we should not
>> save double + double as float even when it fits. It would break
>> DOUBLE data type, which we are going to introduce, because from
>> what I understood, it is going to store MP_DOUBLE only.
>>
>> On the other hand, DOUBLE is not implemented yet
> 
> I guess double is already on board. See d8193eb1c
> 
>> and when it will
>> be implemented, we may decide to allow to store MP_FLOAT there.
>>
>>  src/box/xrow_update_field.c | 18 ++++++++--
>>  test/box/update.result      | 66 +++++++++++++++++++++++++++++++++++++
>>  test/box/update.test.lua    | 46 ++++++++++++++++++++++++++
>>  3 files changed, 127 insertions(+), 3 deletions(-)
>>
>> diff --git a/src/box/xrow_update_field.c b/src/box/xrow_update_field.c
>> index 7c0f5fb5e..31429ee37 100644
>> --- a/src/box/xrow_update_field.c
>> +++ b/src/box/xrow_update_field.c
>> @@ -400,13 +400,25 @@ xrow_update_arith_make(struct xrow_update_op *op,
>>  			unreachable();
>>  			break;
>>  		}
>> -		if (lowest_type == XUPDATE_TYPE_DOUBLE) {
>> +		float fc = (float) c;
>> +		/*
>> +		 * A value may be saved as double even if it looks
>> +		 * like fitting a float. For example, 0.01 + 0.01
>> +		 * may be stored as double. This is because
>> +		 * 0.01 may be stored as 0.009999999999999, what
>> +		 * looks like double precision. And there is no
>> +		 * way how to check if this is actually 0.01.
>> +		 * By the same reason FLT_MAX can't be used to
>> +		 * detect whether a value fits float, because it
>> +		 * may be <= FLT_MAX, but may have a double
>> +		 * precision in its fraction part.
>> +		 */
>> +		if (c != (double) fc) {
>>  			ret->type = XUPDATE_TYPE_DOUBLE;
>>  			ret->dbl = c;
>>  		} else {
>> -			assert(lowest_type == XUPDATE_TYPE_FLOAT);
>>  			ret->type = XUPDATE_TYPE_FLOAT;
>> -			ret->flt = (float)c;
>> +			ret->flt = fc;
>>  		}
>>  	} else {
>>  		decimal_t a, b, c;


More information about the Tarantool-patches mailing list