【问题标题】:square root using Babylonian method returns wrong value?使用巴比伦方法的平方根返回错误值?
【发布时间】:2015-09-23 18:58:22
【问题描述】:

对于函数isqroot(),使用巴比伦方法计算平方根,精度为一级,并在结构中返回。

我无法将值返回给结构,并且当我编译它时返回垃圾值。

这是我的代码:

#include<stdio.h>
#include<stdlib.h>
#include<math.h>

struct rootStruct {
    int rootInt;
    int rootFraction;
};

typedef struct rootStruct RootStruct;
RootStruct* isqroot (int n) {
    /*We are using n itself as initial approximation*/
    RootStruct* root=(RootStruct* )malloc(sizeof(RootStruct));
    float x = n;
    float y = 1;
    float e = 0.1; /* e decides the accuracy level*/

    while(x - y > e) {
        x = (x + y)/2;
        y = n/x;
    }
    root->rootInt = (int)x/2;
    root->rootFraction = (int)(x-root->rootInt)*100;
    return root;
}

int main(){
    RootStruct* roo+t=(RootStruct* )malloc(sizeof(RootStruct));
    printf("the sqrt is %d\n%d\n",root->rootInt,root->rootFraction);
    return 0;
}

这段代码有什么问题?

【问题讨论】:

  • 它甚至编译了吗?你甚至没有调用你的函数。
  • 在您的设计中,您分配少量内存来保存生成的根。如果你用malloc分配内存,你也必须free它,这很繁琐。与数组不同,结构可以作为值传递,因此您可以在没有指针和额外内存管理开销的情况下重写此代码。
  • @MOehm,传递一个大于某个非常小的大小的结构会导致对 memcpy() 的许多隐藏调用,并留出内存供 memcpy() 调用使用。该内存不能用于其他任何事情。 IE。通过传递整个结构来传递结构是一种非常糟糕的做法。将指针传递给结构是一种更好的做法。
  • 在调用系统函数malloc()时,始终检查(!=NULL)返回值以确保操作成功
  • @user3629249:有问题的结构“称重”两个整数,相当于现代系统中指针的大小。我怀疑它是通过memcpy 复制的。另请注意,没有传入结构,而是返回了一个结构。在此处返回指针会产生进一步的后果:指针必须指向静态内存或新分配的内存。静态内存意味着结果被后续调用覆盖;分配的内存意味着调用代码必须显式地释放它。在我看来,如果你想保留 x = sqrt(8) 语义,在这里返回一个结构是更好的选择。

标签: c struct


【解决方案1】:

您永远不会调用 isqroot()...,因此永远不会设置 root-&gt;rootIntroot-&gt;rootFraction

你也有错别字

RootStruct* roo+t=(RootStruct* )malloc(sizeof(RootStruct));

应该是

RootStruct* root=(RootStruct* )malloc(sizeof(RootStruct));

没有+。但是,这是不必要的,因为您在 isqroot() 中分配内存并且可能应该替换为

RootStruct* root = isqroot(9);

那别忘了free()main()末尾的内存。


请注意,您也是shouldn't case the result of malloc() in C


你也实现了算法不正确,应该是

RootStruct* isqroot (int n) {
    RootStruct* root=(RootStruct* )malloc(sizeof(RootStruct));

    float y = 1;
    float e = 0.1; /* e decides the accuracy level*/

    while(fabs(n - y*y) > e) {
        y = (y + (n / y)) / 2;
    }

    root->rootInt = (int) y;
    root->rootFraction = (int) (y - root->rootInt) * 100;

    return root;
}

完整的修正程序在哪里

#include <stdio.h>
#include <stdlib.h>
#include <math.h>

struct rootStruct {
    int rootInt;
    int rootFraction;
};

typedef struct rootStruct RootStruct;

RootStruct* isqroot (int n) {
    RootStruct* root=(RootStruct* )malloc(sizeof(RootStruct));

    float y = 1;
    float e = 0.1; /* e decides the accuracy level*/

    while(fabs(n - y*y) > e) {
        y = (y + (n / y)) / 2;
    }

    root->rootInt = (int) y;
    root->rootFraction = (int) (y - root->rootInt) * 100;

    return root;
}

int main() {
    RootStruct* root = isqroot(9);
    printf("The sqrt is %d.%d\n", root->rootInt, root->rootFraction);
    return 0;
}

Computing Square Roots 上的维基百科文章在Babylonian method 上有一个非常容易理解的部分。

【讨论】:

  • 嗯..我认为它不会起作用。我不是说你错了。但是为什么要在函数内部和main 中声明root 呢?
  • @ameyCU 哪个部分? isqroot() 中的代码对我来说似乎坏了,但由于 isqroot() 未被调用,我已经回答了有关垃圾值的问题。
  • 即使在你告诉我的更改之后,他的代码也无法正常工作。不必要的演员阵容和许多事情。
  • @ameyCU 是的,我同意,即使在我进行了更改之后,他的代码也无法正常工作。他错误地执行了算法。我已经回答了他无法返回 struct 并获取垃圾值的问题。
  • @ameyCU 编辑修复了他在编码算法时的错误。
猜你喜欢
  • 1970-01-01
  • 2020-05-12
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2017-09-25
  • 1970-01-01
  • 1970-01-01
  • 2020-09-13
相关资源
最近更新 更多