数组中两个值的除法始终返回0

时间:2018-08-18 23:40:03

标签: c floating-point division

我有这个函数可以返回一个应该为1或2或4的数字,但是当除法发生时,变量 duracion 总是得到值0。我已经尝试了很多更改,但是没有一个解决方案。

// Converts a fraction formatted as X/Y to eighths
int duration(char* fraction)
{
    // TODO
    if (strlen(fraction) == 3)
    {
        // Asignacion de los caracteres de la fraccion a un array para 
           convertirlos en numeros despues.
        int a = atoi(&fraction[0]);
        int b = atoi(&fraction[2]);
        // Busqueda de errores --------------------------------------- 
        if ((fraction[0] != '1') && (fraction[0] != '3'))
        {
            fprintf(stderr, "octave most be formated as X/Y, where X 
                    can't be greater than 8\n");
            return 1;
        }
        else if (fraction[1] != '/')
        {
            fprintf(stderr, "octave most be formated as X/Y\n");
            return 1;
        }
        else if ((fraction[2] % 2 != 0) || (fraction[2] < 0))
        {
            fprintf(stderr, "octave most be formated as X/Y, where Y 
                    most be a positive pair number\n");
            return 1;
        }
        // Fin de busqueda de errores -------------------------------

        float duracion = (a / b) * 8;
        return duracion;
    }
    else
    {
        fprintf(stderr, "Note lenght most be formated as X/Y\n");
        return 1;
    }
}

3 个答案:

答案 0 :(得分:3)

尽管此代码有几个问题,但我将首先回答您的直接问题。 您的问题出在行中

float duracion = (a / b) * 8;

从您的代码中,我可以看到您假设a < b。这意味着:a / b < 1。 由于abint,因此您正在执行整数除法,这意味着除法的整数结果总是总是被截断为零。

这里是一种可能的解决方案(不过,请确保这不是您真正想要的):

return (8.0 * a / b);

这是另一个(也许这是您实际需要的?):

return b / a;

现在有一些一般性说明(假设您使用的是C99)。

您的问题标题实际上是“来自数组的两个值的除法总是返回0”,这是来自字符串的值。 但这无关紧要,因为如果您只说“两个整数值的除法总是返回0”,那么Google会为您找到答案。

如果您假定分数的两个部分始终都是单个ASCII字符,则可以这样写:

int a = fraction[0] - '0';
int b = fraction[2] - '0';

如果这不是假设,则首选使用“ sscanf”,因为它可以处理大多数用例,甚至包括“ -16/8”之类的分数。

int a,b;
int ret = sscanf(fraction,"%d / %d", &a, &b);

还请注意,此行是错误的,无法按您希望的方式工作:

else if ((fraction[2] % 2 != 0) || (fraction[2] < 0))

通常,您应该对字符串上的“ a”和“ b”值以及值进行所有检查。

此外,习惯上尝试接受任何看起来有效的输入,而不是将用户限制在某些过度指定的模式上。因此,不应将字符串的长度限制为3,并且应在元素之间留出空格。

此外,除非您的意图是明确标记,否则您应该返回有效的答复,对于您的情况,该答复为“ 1”检测到错误。 选择一个像“ -1”这样的数字,或者更好的是,定义一个负值的枚举并返回特定的错误,而不是在函数内部打印出来。

P.S。  在音乐中,音符持续时间比基音长是完全合法的。所以像16/8这样的东西通常是可以的。但这是音乐理论,而不是编程问题。

答案 1 :(得分:0)

问题是a和b都是int。因此它正在执行int除法。

尝试强制转换为(float)a / b * 8

或者您可以使用atof代替atoi并将a和b声明为float

答案 2 :(得分:0)

就这样:     float duracion =(a / b)* 8;

修改:     float duracion =(a * 1.0 / b)* 8;

尝试