我想比较两个数字“a”和“b”,如果a大于b,我想将另一个双c设置为1,否则我想将c设置为0.
以下是我到目前为止所做的事情 -
#include <stdio.h>
#include <math.h>
int main() {
double a = 0.01242;
double b = 0.04231;
double c = ceil(fmod(a,b));
//c should be 1 if a > b or else it should be 0
}
我的问题是它适用于某些数字,但通常ceil()会返回大于1的数字。
我想在不使用任何包含布尔返回类型的运算符的情况下执行此操作。
答案 0 :(得分:0)
我认为您可以使用以下表达式来查找a和b之间的最大值,并使用max(a, b) ^ b
找到它们是否相等然后将max(a, b) ^ b
的结果赋给c。(^是按位xor)
max(a, b) = 1 / 2. * (a + b + sqrt((a - b) * (a - b)));
或
max(a, b) = 1 / 2. * (a + b + fabs(a-b));
我们不能在double上使用^运算符,所以如果你想使用双重跟随程序,也许可以完成你的工作:
#include <stdio.h>
#include <math.h>
double max(double a, double b)
{
return 1 / 2. * (a + b + fabs(a-b));
}
int main(int argc, char *argv[])
{
double b = 0.01242;
double a = 0.04231;
printf("%g\n", max(a, b));
int c = ceil(max(a, b) / b);
c = (c + 1) % c;
/* c should be 1 if a > b or else it should be 0 */
printf("%d\n", c);
}
答案 1 :(得分:0)
有趣的问题我解决了这个问题:
//---------------------------------------------------------------------------
double fpu_cmp(double a,double b)
{
// a> b -> c=1
// a<=b -> c=0
double c; // a<=b a>=b
c=a-b; // c<=0.0 c>0.0
c/=fabs(c)+1e-323; // c={-1,0} c=+1.0
c+=fabs(c); // c=0.0 c=+2.0
c*=0.5; // c=0.0 c=+1.0
return c;
}
//---------------------------------------------------------------------------
c
a<=b
c
a>b
a,b=<-3,+3>
上使用步骤0.01
进行测试且没有错误1e-323
不断将1.0
更改为0.99999999...9
return ceil(c);
,但我认为在当前状态下已经可以了[注释]
fabs
可以通过单位操作完成c*=0.5
只是指数递减(位掩码)1e-323
只是为了避免被零除(但如果比较非常接近的数字可以显着改变结果)这个常数是避免被零除的最小值。如果你计算的数字至少比100
倍大,那么你应该没问题答案 2 :(得分:0)
在IEEE-754中,您可以将浮点值作为符号幅度整数值进行比较。所以我在这里使用它。整数比较类似于我在this answer中使用的整数比较,但是是无符号版本。以下是转换为无分支
之前的原始版本此处减号运算符不像其他问题一样使用,但您可以通过转换回使用减号来缩短代码。
int isGreaterI(uint64_t x, uint64_t y)
{
if ((x ^ y) >> 63) // never happens as we only pass absolute values as below
{
return (x >> 63) & 1;
}
else
{
uint64_t xm = ~x + 1ULL;
uint64_t diff = y + xm;
return diff >> 63;
}
}
int isGreaterF(double a, double b)
{
uint64_t ai = *((uint64_t*)(&a));
uint64_t bi = *((uint64_t*)(&b));
int result;
if ((ai ^ bi) >> 63) // different signs
{
result = bi >> 63; // bi < 0, ai > 0
}
else
{
uint64_t sign = ai >> 63;
result = isGreaterI(ai, bi);
if (sign)
result = !result;
}
return result;
}
在if
块中复用分支的结果以删除条件并删除不必要的分支后,我们有以下最终版本
int isGreaterMagnitude(uint64_t x, uint64_t y)
{
uint64_t xm = ~x + 1ULL;
uint64_t diff = y + xm;
return diff >> 63;
}
int isGreaterF(double a, double b)
{
uint64_t ai = *((uint64_t*)(&a));
uint64_t bi = *((uint64_t*)(&b));
uint64_t mask = ((ai ^ bi) >> 63) + (~0ULL); // mask = 0 if a and b have different signs
uint64_t r1 = bi >> 63;
uint64_t sign = (int64_t)ai >> 63;
uint64_t r2 = isGreaterMagnitude(ai, bi);
r2 = (r2 & ~sign) | ((1 - r2) & sign);
return (r1 & ~mask) | (r2 & mask);
}