gpt4 book ai didi

c - 浮点舍入错误将报告的结果移动到范围内

转载 作者:太空宇宙 更新时间:2023-11-04 06:14:55 25 4
gpt4 key购买 nike

我正在开发一个功能来报告测试结果以及该特定测试结果的下限和上限。这三个值将使用指定的公式 (aX + b)/c 进行转换,其中 X 为 testResult/lowerLimit/upperLimit,a、b 和 c 为 float 。

如果报告的测试结果在转换前在规定范围内/外,转换后也应在规定范围内/外,以确保报告结果的有效性。

我已经确定了两种情况,其中无效测试结果在转换后会移动到范围内,但我还没有找到测试结果在转换前在范围内而在转换后将超出指定限制的情况。这种情况还能发生吗?我不相信?可以吗?

下面是生成我提到的两种情况的一些代码以及更正以确保报告的测试结果的有效性。

TLDR:下面代码中的 ((TRUE == insideLimitBefore) && (FALSE == insideLimitAfter)) 情况会发生吗?

#include <stdio.h>
#include <stdint.h>

#define TRUE (uint8_t)0x01
#define FALSE (uint8_t)0x00

int32_t LinearMapping(const int32_t input);
void Convert(int32_t testResult, int32_t lowerLimit, int32_t upperLimit);

int main(void)
{

int32_t lowerLimit = 504;
int32_t testResult = 503;
int32_t upperLimit = 1000;

printf("INPUT:\n\tLower limit:\t%d\t\n\tTest result:\t%d\t\n\tUpper limit:\t%d\t\n", lowerLimit, testResult, upperLimit);
Convert(testResult, lowerLimit, upperLimit);

lowerLimit = 500;
testResult = 504;
upperLimit = 503;

printf("INPUT:\n\tLower limit:\t%d\t\n\tTest result:\t%d\t\n\tUpper limit:\t%d\t\n", lowerLimit, testResult, upperLimit);
Convert(testResult, lowerLimit, upperLimit);

return 0;
}

int32_t LinearMapping(const int32_t input)
{
float retVal;

const float a = 1.0;
const float b = 1.0;
const float c = 2.3;

retVal = a * input;
retVal += b;
retVal /= c;

return (int32_t)retVal;
}

void Convert(int32_t testResult, int32_t lowerLimit, int32_t upperLimit)
{
uint8_t insideLimitAfter;
uint8_t belowLowerLimit;
uint8_t insideLimitBefore = ((lowerLimit <= testResult) && (testResult <= upperLimit)) ? TRUE : FALSE;

if (FALSE == insideLimitBefore)
{
/* testResult is either below or above lowerLimit/upperLimit respectively */
if (testResult < lowerLimit)
{
belowLowerLimit = TRUE;
}
else /* testResult > upperLimit */
{
belowLowerLimit = FALSE;
}
}

testResult = LinearMapping(testResult);
lowerLimit = LinearMapping(lowerLimit);
upperLimit = LinearMapping(upperLimit);

insideLimitAfter = ((lowerLimit <= testResult) && (testResult <= upperLimit)) ? TRUE : FALSE;

if ((FALSE == insideLimitBefore) && (TRUE == insideLimitAfter))
{
if (TRUE == belowLowerLimit)
{
printf("OUTPUT:\n\tLower limit:\t%d\t\n\tTest result:\t%d\t\n\tUpper limit:\t%d\t\n", lowerLimit+1, testResult, upperLimit);
}
else /* belowLowerLimit == FALSE => testResult > upperLimit */
{
printf("OUTPUT:\n\tLower limit:\t%d\t\n\tTest result:\t%d\t\n\tUpper limit:\t%d\t\n", lowerLimit, testResult, upperLimit-1);
}
}
else if ((TRUE == insideLimitBefore) && (FALSE == insideLimitAfter))
{
/* Is this case even possible? */
}
else
{
/* Do nothing */
}
}

最佳答案

to find a case where the test result is inside the range before the conversion and will be outside the specified limits after conversion. Can this case even occur?

不,考虑到理智a,b,c, lowerLimit, testResult, upperLimit .

给定 3 个值 lo,x,hi那是lo <= x <= hiLinearMapping() 中的线性转换之前lo_new <= x_new <= hi_new只要转换是(正)线性的(不除以 0,abc 不是非数字),就会保持相同的关系。没有转换 float这超出了 int32_t 的范围.

主要原因是 x 的边缘情况就在里面或在极限处,[lo...hi] , LinearMapping()可能会降低所有 3 个的有效精度。新的 x现在可能等于 lohi==赞成“在范围内”。所以 lo <= x <= hi 没有变化.

OP 最初发现“无效测试结果将在转换后移动到范围内”的示例,因为 x就在外面[lo...hi]现在有效的精度降低了x等于 lohi .自 ==倾向于“在范围内”,可以看到从外到内的移动。

注意:如果 LinearMapping()有一个像 -1 这样的负斜率,然后是 lo <= x <= hi很容易被打破。作为1 <= 2 <= 3 --> -1 > -2 > -3 .这使得 lowerLimit > upperLimit任何 x 都不能满足“在范围内” .


供引用,OP 的代码已简化:

#include <stdio.h>
#include <stdint.h>

int LinearMapping(const int input) {
const float a = 1.0;
const float b = 1.0;
const float c = 2.3;
float retVal = a * input;
retVal += b;
retVal /= c;
return (int) retVal;
}

void Convert(int testResult, int lowerLimit, int upperLimit) {
printf("Before %d %s %d %s %d\n", lowerLimit,
lowerLimit <= testResult ? "<=" : "> ", testResult,
testResult <= upperLimit ? "<=" : "> ", upperLimit);
testResult = LinearMapping(testResult);
lowerLimit = LinearMapping(lowerLimit);
upperLimit = LinearMapping(upperLimit);
printf("After %d %s %d %s %d\n\n", lowerLimit,
lowerLimit <= testResult ? "<=" : "> ", testResult,
testResult <= upperLimit ? "<=" : "> ", upperLimit);
}

int main(void) {
Convert(503, 504, 1000);
Convert(504, 500, 503);
return 0;
}

输出

Before 504 >  503 <= 1000
After 219 <= 219 <= 435

Before 500 <= 504 > 503
After 217 <= 219 <= 219

关于c - 浮点舍入错误将报告的结果移动到范围内,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/47940153/

25 4 0
Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
广告合作:1813099741@qq.com 6ren.com