如何检查一个数字是浮点数还是整数?

859

如何判断一个数字是float还是integer

1.25 --> float  
1 --> integer  
0 --> integer  
0.25 --> float

53
我理解您的问题,但是为了明确:<nit-pick> JavaScript没有不同的整数和浮点数字类型。在JavaScript中每个数字都只是一个Number</nit-pick> - Matt Ball
5
根据您的理解,“无穷大”是整数还是非整数?这里的答案在这个问题上分布得相当均匀。 - Mike Samuel
14
为了数学上的准确性:由于无限大不是实数,而所有整数都是实数,因此“无穷大”不能被视为整数。 - rvighne
2
@rvighne,我认为我们都同意无穷大和NaN不是实数的事实意味着IEEE-754浮点数不是实数的子集。所有基于IEEE-754的数值分析都必须处理这个事实。我不明白的是你如何认为这个事实决定了is_integral在基数方面应该如何行事。就个人而言,我认为((x%1)==0)是一个很好的代理,并且已经被IEEE-754完全指定,因此没有必要争论不同数字线之间的对应关系。 - Mike Samuel
5
你认为 1.0 是整型还是浮点型? - vol7ron
显示剩余7条评论
52个回答

8
我们可以使用isInteger函数进行检查。 即,数值类型为整型(number)时返回true,为浮点型(float)时返回false。
console.log(Number.isInteger(2)),<BR>

Will return true

console.log(Number.isInteger(2.5))

Will return false


但是 Number.isInteger(2.0) 也会返回 true - Sơn Trần-Nguyễn

7

正如其他人所提到的,JS中只有double类型。那么如何定义一个数字是整数呢?只需检查舍入后的数字是否等于它本身:

function isInteger(f) {
    return typeof(f)==="number" && Math.round(f) == f;
}
function isFloat(f) { return typeof(f)==="number" && !isInteger(f); }

4
可能需要检查该值是否为数字... isFloat('abc')返回 true - Dagg Nabbit
isFloat(NaN) // true - shime
@shime:很好的发现。NaN在技术上虽然是浮点数...但这取决于具体的使用情况。 - Claudiu

6

这是我用来表示整数的:

Math.ceil(parseFloat(val)) === val

简洁、精炼,总是有效。如果我没记错的话,这就是David Flanagan所建议的。


我喜欢这个答案,因为它是一个简短、简单的回答,不依赖于神秘的位运算。 - Jim
Why parseFloat ? - doubleOrt

6

简单整数测试:

if( n === parseInt(n) ) ...

有道理:如果JavaScript可以将某个东西转换为整数,并且通过转换它变得完全相同,那么您的操作数就是整数。

控制台的测试用例:

x = 1;     x===parseInt(x); // true
x = "1";   x===parseInt(x); // false
x = 1.1;   x===parseInt(x); // false, obviously

// BUT!

x = 1.0;   x===parseInt(x); // true, because 1.0 is NOT a float!

这让很多人感到困惑。当某些东西是.0时,它就不再是浮点数了,它是一个整数。或者你可以称其为“数字类型”,因为像在C语言中那样没有严格的区分。好的旧时光。基本上,你能做的只是检查是否为整数,并接受1.000是整数的事实。
有趣的副作用
有关巨大数字的评论。对于这种方法,巨大的数字并不是问题;每当parseInt无法处理该数字(因为它太大),它将返回与实际值不同的其他内容,因此测试将返回FALSE。看:
var a = 99999999999999999999;
var b = 999999999999999999999; // just one more 9 will kill the show!

var aIsInteger = (  a===parseInt(a)  )?"a is ok":"a fails";
var bIsInteger = (  b===parseInt(b)  )?"b is ok":"b fails";

alert(aIsInteger+"; "+bIsInteger);

我在2014年在IE8上测试过,然后在2021年在Chrome上测试过,两者都返回“a is ok; b fails”,这意味着如果一个数字太大,它就不再是整数了。引用经典名言:“20位数字应该足够了”。

如果您只需要检查整数(从数学角度),那么这是可以的,但是如果您想确保它们实际上像整数一样工作(从计算机角度),对于大量数字来说,这将是不正确的。请参见此评论。 - Dagg Nabbit
我的意思是,按位运算符(将数字视为32位整数)在无法表示为32位整数的数字上不会产生预期结果,因此这些数字不应被标识为整数。这与建议中的Number.isInteger的工作方式一致。 - Dagg Nabbit
某些东西可以是真正的整数,而不必以一种特定的方式存储。我理解你的观点,但整数之所以是整数,是因为它们没有小数部分,并且可以任意相加/相减而不会得到类似于浮点数的结果。如果您将数字视为位字段,则假设了有关它们如何存储的某些内容,这在我看来是一种实际工作但不是100%可靠的方法。如果您正在寻找“以某种方式存储的整数”,那么我不确定是否有单行测试可以在所有平台上安全使用。 - dkellner
可以表示为32位整数的数字使用位运算符可以100%可靠地工作。您并没有“假设它们如何存储”;根据规范,这些数字将转换为带符号的32位大端二进制补码整数。不能用此格式表示的数字不应被视为整数。同样,这与Number.isInteger的工作方式相一致。单行测试是n === (n | 0),如另一个答案所示。 - Dagg Nabbit
我认为这不正确(根据规范,它们不是32位整数而是64位浮点数);此外,我认为我们在这里的论点对原始问题没有任何附加价值。无论如何,谢谢。 - dkellner
显示剩余5条评论

5
尝试了这里的一些答案后,我写出了这个解决方案。这个方案也适用于字符串中包含数字的情况。
function isInt(number) {
    if(!/^["|']{0,1}[-]{0,1}\d{0,}(\.{0,1}\d+)["|']{0,1}$/.test(number)) return false;
    return !(number - parseInt(number));
}

function isFloat(number) {
    if(!/^["|']{0,1}[-]{0,1}\d{0,}(\.{0,1}\d+)["|']{0,1}$/.test(number)) return false;
    return number - parseInt(number) ? true : false;
}

    var tests = {
        'integer' : 1,
        'float' : 1.1,
        'integerInString' : '5',
        'floatInString' : '5.5',
        'negativeInt' : -345,
        'negativeFloat' : -34.98,
        'negativeIntString' : '-45',
        'negativeFloatString' : '-23.09',
        'notValidFalse' : false,
        'notValidTrue' : true,
        'notValidString' : '45lorem',
        'notValidStringFloat' : '4.5lorem',
        'notValidNan' : NaN,
        'notValidObj' : {},
        'notValidArr' : [1,2],
    };

    function isInt(number) {
        if(!/^["|']{0,1}[-]{0,1}\d{0,}(\.{0,1}\d+)["|']{0,1}$/.test(number)) return false;
        return !(number - parseInt(number));
    }
    
    function isFloat(number) {
        if(!/^["|']{0,1}[-]{0,1}\d{0,}(\.{0,1}\d+)["|']{0,1}$/.test(number)) return false;
        return number - parseInt(number) ? true : false;
    }

    function testFunctions(obj) {
        var keys = Object.keys(obj);
        var values = Object.values(obj);

        values.forEach(function(element, index){
            console.log(`Is ${keys[index]} (${element}) var an integer? ${isInt(element)}`);
            console.log(`Is ${keys[index]} (${element}) var a float? ${isFloat(element)}`);
        });
    }

    testFunctions(tests);


5
var isInt = function (n) { return n === (n | 0); };

我从未遇到过这个无法完成的情况。

4
因为那超出了最大整数值。 - ankr
但是你可以设置一个Int的最大长度,对吧?如果我不知道Int的长度会返回什么怎么办? - itsme
这段代码对于整数小于Number.MAX_SAFE_INTEGER但大于2^32会出现错误。 :-( - Kris Jenkins
1
@ekussberg 是的,因为2是一个整数,而23被视为函数的第二个参数。在JavaScript中,小数使用点作为分隔符 - 所以应该是2.23 - ankr
1
或者说这是一个学习位运算的绝佳机会。你将从中受益匪浅。 - ankr
显示剩余2条评论

5
任何小数部分为零的浮点数(例如1.0、12.00、0.0)都会被隐式转换为整数,因此无法检查它们是否为浮点数。

5
!!(24%1) // false
!!(24.2%1) // true

!!(24.0%1) 是假的 - tim-phillips

4

这取决于您想要实现什么。如果您想要“模拟”强类型语言,那我建议您不要尝试。正如其他人所提到的,所有数字具有相同的表示(相同的类型)。

使用像 Claudiu 提供的东西:

isInteger(1.0) -> true

这看起来很合理,但在像C这样的语言中,您将得到 false


3
function isInteger(n) {
   return ((typeof n==='number')&&(n%1===0));
}

function isFloat(n) {
   return ((typeof n==='number')&&(n%1!==0));
}

function isNumber(n) {
   return (typeof n==='number');
}

整数不是浮点数?这可真是新闻啊。 - Maarten Bodewes

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接