[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