douchang8758 2014-08-08 08:10
浏览 16
已采纳

is_int和模数%1之间的差异?

I ran the following code, to test if a number was divisible by 7 and then return only if true.

is_int gives me what I think, but using modulus to check if it is an integer (%1) I get floats too.

for ($i = 100; $i < 222; $i++) {
        $dividedBy7 = $i/7;
        if(is_int($dividedBy7)){
            echo 'is int thinks '.$dividedBy7.'</br>';
        }
        if($dividedBy7 % 1 == 0){
            echo 'modulus thinks '.$dividedBy7.'</br>';
        }
}

OUTPUT

modulus thinks 14.2857142857, modulus thinks 14.4285714286 etc

is int thinks15, 16 etc

What is wrong with my understanding of modulus?

EDIT I appreciate that %7 is the correct use of modulus in this example, but this is a simplification of the situation.

  • 写回答

2条回答 默认 最新

  • dsklfsdlkf1232 2014-08-08 08:24
    关注

    Answering your question: modulus operator (so, %) is an integer operator. Thus, it expects operands to be integer. If not, it will convert them to integer. That stands from implementation:

    ZEND_API int mod_function(zval *result, zval *op1, zval *op2 TSRMLS_DC) /* {{{ */
    {
        zval op1_copy, op2_copy;
        long op1_lval;
    
        zendi_convert_to_long(op1, op1_copy, result);
        op1_lval = Z_LVAL_P(op1);
        zendi_convert_to_long(op2, op2_copy, result);
    
        if (Z_LVAL_P(op2) == 0) {
            zend_error(E_WARNING, "Division by zero");
            ZVAL_BOOL(result, 0);
            return FAILURE;         /* modulus by zero */
        }
    
        if (Z_LVAL_P(op2) == -1) {
            /* Prevent overflow error/crash if op1==LONG_MIN */
            ZVAL_LONG(result, 0);
            return SUCCESS;
        }
    
        ZVAL_LONG(result, op1_lval % Z_LVAL_P(op2));
        return SUCCESS;
    }
    

    So as you can see,

        zendi_convert_to_long(op1, op1_copy, result);
        op1_lval = Z_LVAL_P(op1);
        zendi_convert_to_long(op2, op2_copy, result);
    

    will produce the conversion. That's why it's:

    var_dump(14.4 % 7); //int(0) since (int)14.4 is 14 which is dividable by 7
    

    Proper way would be to check the reminder from division by 7, thus,

    if($i % 7 == 0)
    {
       //$i is dividable by 7
    }
    

    Use integer operators with integer operands to avoid any unexpected behavior.

    本回答被题主选为最佳回答 , 对您是否有帮助呢?
    评论
查看更多回答(1条)

报告相同问题?

悬赏问题

  • ¥15 stm32开发clion时遇到的编译问题
  • ¥15 lna设计 源简并电感型共源放大器
  • ¥15 如何用Labview在myRIO上做LCD显示?(语言-开发语言)
  • ¥15 Vue3地图和异步函数使用
  • ¥15 C++ yoloV5改写遇到的问题
  • ¥20 win11修改中文用户名路径
  • ¥15 win2012磁盘空间不足,c盘正常,d盘无法写入
  • ¥15 用土力学知识进行土坡稳定性分析与挡土墙设计
  • ¥70 PlayWright在Java上连接CDP关联本地Chrome启动失败,貌似是Windows端口转发问题
  • ¥15 帮我写一个c++工程