【问题标题】:floor()/int() function implementatonfloor()/int()函数实现
【发布时间】:2011-07-04 15:01:12
【问题描述】:

有人知道Int()floor() 的方法/功能是如何实现的吗? 我正在寻找一个相应的实现,如下是abs()函数。

Int Abs (float x){
  if x > 0 
      return x;
   else
      return -x
}

在不使用模运算符的情况下,我正在努力寻找解决方案。

【问题讨论】:

  • 说明为什么你需要这会很好。
  • @WinstonEwert 也许他想摆脱分支。
  • @kvantour,7 年后我怀疑他仍然想做他想做的任何事情。无论如何,这个问题看起来很像“我如何在不消耗任何氧气的情况下呼吸”

标签: function implementation


【解决方案1】:

我觉得像

floor(n) = n - (n % 1)

应该可以解决问题。

【讨论】:

  • 这个答案非常适合内置地板功能不可用的地板,它可以作为模数功能的实用解释。谢谢!
  • 这是完美的。 ceil() 有类似的实现吗?
  • 是的,我在发表评论后大约 5 秒就知道了。谢谢。
  • 这不是因为否定n 而失败吗? floor(-1.5) 给我 (-1)
  • 对于那些想要回复有关 ceil 的评论的人,只需看看 floor 的作用。其中 (x) = 0.3 0.3 - (0.3 % 1) = 0.3 - 0.3 = 0 所以对于 ceil,只需首先计算 0.3 的倒数,即 1 -.3,即 0.7。 ceil(x) = (1 - x) + (x % 1);
【解决方案2】:

使用IEEE 754 binary floating point representation 一种可能的解决方案是:

float myFloor(float x)
{
  if (x == 0.0)
    return 0;

  union
  {
    float input;   // assumes sizeof(float) == sizeof(int)
    int   output;
  } data;

  data.input = x;

  // get the exponent 23~30 bit    
  int exp = data.output & (255 << 23);
  exp = exp >> 23;

  // get the mantissa 0~22 bit
  int man = data.output & ((1 << 23) - 1);

  int pow = exp - 127;
  int mulFactor = 1;

  int i = abs(pow);
  while (i--)
    mulFactor *= 2;

  unsigned long long denominator = 1 << 23;
  unsigned long long numerator = man + denominator;

  // most significant bit represents the sign of the number
  bool negative = (data.output >> 31) != 0;

  if (pow < 0)
    denominator *= mulFactor;
  else
    numerator *= mulFactor;

  float res = 0.0;
  while (numerator >= denominator) {
    res++;
    numerator -= denominator;
  }

  if (negative) {
    res = -res;
    if (numerator != 0)
      res -= 1;
  }

  return res;
}


int main(int /*argc*/, char **/*argv*/)
{
  cout << myFloor(-1234.01234) << " " << floor(-1234.01234) << endl;

  return 0;
}

【讨论】:

  • 这与Michal'sSeronis'sTheJubilex's 的答案有何不同?
  • @FaridNouriNeshat 这个答案实际上可能与其他答案相同,但显示了如何使用位级指令实现int(value)。 (如果我最初提出这个问题,这就是我要寻找的答案,而我会很失望地得到其他看起来很明显的答案。)
【解决方案3】:
private static int fastFloor(double x) {
    int xi = (int)x;
    return x < xi ? xi - 1 : xi;
}

这是一种类似于 Michal Crzardybons answer 的方法,但它避免了条件分支并且仍然正确处理负数。

【讨论】:

  • 我猜你也有条件
  • 是的。我没有说它避免了所有分支。我说它避免了'a'条件分支。他使用 2 个分支。我的使用 1。
  • 这是无效的,因为 fastFloor(-2) 将返回 -3 而不是 -2
【解决方案4】:

如果 'int' 类型的结果足够了,那么这里有一个简单的替代方案:

int ifloor( float x )
{
    if (x >= 0)
    {
        return (int)x;
    }
    else
    {
        int y = (int)x;
        return ((float)y == x) ? y : y - 1;
    }
}

【讨论】:

    【解决方案5】:
    int(x)   = x - x%1
    floor(x) = int(x)-(x<0 && x%1!=0)
    ceil(x)  = int(x)+(x>0 && x%1!=0)
    round(x) = floor(x)+(x>0&&x%1>=0.5)+(x<0&&(1+x%1)%1>=0.5)
    

    注意: round(x) 未实现为 floor(x+0.5),因为这将在 x=0.5-2^-54 处失败

    注意:假设逻辑运算转换为整数值,1 表示真,0 表示假


    实施完成后,它们与int(x)floor(x)ceil(x)round(x) 中定义的域相匹配

    【讨论】:

      【解决方案6】:

      最佳答案不适用于负数,因此我对其进行了修改:

      floor(n) = n - (n % 1 >= 0 ? n%1: (1 + n % 1))
      
      ceil(n) = -floor(-n)
      

      【讨论】:

        【解决方案7】:

        #include<iostream>
        
        int myfloor(int x) {
            if (x > 0)
                return x;
            else
                return x - 1;
        }
        int main() {
            double x = -5.9;
            std::cout<<myfloor(x);
            
        
        
        }

        【讨论】:

        • 您发布的代码不是可运行的sn-p(只需单击“运行...”按钮,您就会意识到这一点)!请编辑您的答案并将您的代码格式化为普通代码块(使用简单的三个反引号代码围栏)。
        • 虽然此代码可以解决问题,including an explanation 说明如何以及为什么解决问题将真正有助于提高您的帖子质量,并可能导致更多的赞成票。请记住,您正在为将来的读者回答问题,而不仅仅是现在提问的人。请edit您的回答添加解释并说明适用的限制和假设。
        猜你喜欢
        • 1970-01-01
        • 2017-04-13
        • 2021-03-06
        • 1970-01-01
        • 1970-01-01
        • 2016-08-29
        • 1970-01-01
        • 1970-01-01
        • 2010-09-11
        相关资源
        最近更新 更多