精度为 10、比例为 2 的字段必须舍入到小于 10^8 的绝对值

Posted

技术标签:

【中文标题】精度为 10、比例为 2 的字段必须舍入到小于 10^8 的绝对值【英文标题】:A field with precision 10, scale 2 must round to an absolute value less than 10^8 【发布时间】:2020-03-22 17:45:16 【问题描述】:

我在postgres 数据库中有一个django-field total_price,版本为9.3.11

这是它的当前代码。

total_value = models.DecimalField(decimal_places=100, default=0, max_digits=300)

我想将其转换为正确的小数点后 2 位。所以我写了这段代码

total_value = models.DecimalField(decimal_places=2, default=0, max_digits=10)

我的迁移文件

# -*- coding: utf-8 -*-
from __future__ import unicode_literals

from django.db import models, migrations


class Migration(migrations.Migration):

    dependencies = [
        ('my_table', '0040_my_table_skipped'),
    ]

    operations = [
        migrations.AlterField(
            model_name='my_table',
            name='total_value',
            field=models.DecimalField(default=0, max_digits=10, decimal_places=2),
        ),
    ]

当我运行命令python manage.py migrate

它显示了这个错误

A field with precision 10, scale 2 must round to an absolute value less than 10^8.

知道这是怎么回事吗?

【问题讨论】:

您的数据库中total_price 列中是否有值大于或等于10^8 的值? 是的。桌子很大。就像数千行一样。示例值为 9.99000000000000021316282072803005576133728027343750000000000000000000000000000000000000000000000000000 9.99...大于 10^8;这简直是​​荒谬的精确。尝试找到该(不是整个表)的最大值值。注意:数千行肯定不是很大。 好的。知道了。对不起,我错过了理解。我需要找到最大值,然后需要根据该值增加最大位数 运气好能解决您的问题吗? 【参考方案1】:

之前你有十进制数,比如 Number(300, 100)。我认为你在这个十进制字段中有一些数据。现在将十进制字段更改为 Number(10,2)。所以现在你最多只能保存 99999999.99。但是您的旧数据远不止这些。因为之前您可以保存 300 个最大位数和 100 个小数位的十进制数。

【讨论】:

【参考方案2】:

正如上面提到的@sivakumar-r,这是精度和规模问题。

让我们看看Numeric(precision, scale) 是如何工作的:

假设,如果我们有一个用NUMERIC(10,3) 定义的列。

也就是说,我们总共只能保存 10 位数字,小数点后 3 个空格。

所以在这种情况下您可以保存的范围是: +9999999.999 至 -9999999.999。

一种解决方案可能是:

更改表列以使用类型 NUMERIC 而不使用精度和小数位数。

这将接受小数点前最多 131072 位数字;小数点后最多 16383 位。 As mentioned in postgres:11 Numeric types document.

【讨论】:

【参考方案3】:

如何重现这个 postgresql 错误:

ERROR:  numeric field overflow 
A field with precision 5, scale 4 must round to an absolute value less than 10^1

创建一个包含numeric(4,4) 类型列的postgresql 表,然后尝试从另一个具有numeric(5,4) column type 类型的表中插入数据:

CREATE TABLE mytable( mycolumn numeric(5,4)); 
insert into mytable values(12.3456); 
CREATE TABLE mytable2( mycolumn numeric(4,4)); 
insert into mytable2 ( select * from mytable );    --Error thown on this line

解决方案

增加分配给接收数据的数字列的空间或定义自定义转换函数以使您的数字适合其目标。

【讨论】:

以上是关于精度为 10、比例为 2 的字段必须舍入到小于 10^8 的绝对值的主要内容,如果未能解决你的问题,请参考以下文章

将双精度数舍入到小数点后一位(去掉小数位)

如何优化 spark 函数以将双精度值舍入到小数点后 2 位?

将双精度舍入到最接近的非次正规表示

如何在小数点后将 Dart 中的双精度数舍入到给定的精度?

将双精度数舍入到 x 有效数字

将浮点数舍入到 N 个小数位