手动编码的日志函数无法找到超过 10 的 base-10 日志
Hand-coded log function won't find base-10 logs over 10
作为一项作业,我正在使用 hi-lo 方法编写一个日志函数来找到答案,但是我所拥有的对于大于 10 的数字不起作用,我无法弄清楚为什么
int main() {
double n, nq, x, y;
printf("Enter the number you wish to take to the base 10 logarithm:\n");
scanf("%lf", &x);
double hi = 1;
double lo = 0;
double qlo = 1;
double qhi = 10;
for(int i = 0; i <= 1000; i++) {
n = ((lo + hi)/2);
nq = sqrt(qlo * qhi);
if(nq > x) {
hi = n;
qhi = nq;
} else {
lo = n;
qlo = nq;
}
}
y = n;
printf("the logarithm is equal to %lf\n", y);
printf("%lf\n", log10(x)); // to check result
}
在将 qhi
设置为 10 时,您已将结果限制为 10。将 hi
设置为 1 也无济于事。所以任何大于 10 的输入都会 return 值 1.
如果您希望您的函数适用于更大的域,您需要更加明智地选择 hi
、lo
、qlo
和 qhi
.
这接近于一道数学题。您的函数能够为范围 [1:10] 中的任何值 x 计算 log10(x) 的近似值。背后的原理很简单:log10(1) 是 0,log10(10) 是 1,log10(sqrt(a*b)) 是 1/2(log10(a)+log10(b))。
所以你构建了 2 个序列,第一个使用二分法来近似 x,第二个将近似 log10(x).
简单地说,您必须遵守以下约束:1<=x<=10。
通常的写法是x = m 10n 1<=m<10。如果它 >=10(resp <=1),只需将 x 除以(resp。乘以)十,直到它落在正确的范围内。然后你得到平凡的:log10(x) = n + log10(m)。甚至不要尝试负值...
Enter the number you wish to take to the base 10 logarithm:
1234.5678
50 iterations found 3.091514945509
查看以下更改...
#define _CRT_SECURE_NO_WARNINGS
#include <stdio.h>
#include <math.h>
int main()
{
double x, y;
printf("Enter the number you wish to take to the base 10 logarithm:\n");
scanf("%lf", &x);
double hi = 1;
double lo = 0;
double qlo = 1;
double qhi = 10;
/*if (x <= 0) handle exception log undefined for input <= 0*/
double tmp = 0;
while (x > 10)
{
tmp++;
x /= 10;
}
int i;
double n = 0, nprev = -1;
for (i = 0; i <= 1000 && fabs(n - nprev) > 1.0E-15; i++)
{
nprev = n;
n = ((lo + hi) / 2);
double nq = sqrt(qlo * qhi);
if (nq > x)
{
hi = n;
qhi = nq;
}
else
{
lo = n;
qlo = nq;
}
}
y = tmp + n;
printf("%2d iterations found %.12f",i,y);
}
作为一项作业,我正在使用 hi-lo 方法编写一个日志函数来找到答案,但是我所拥有的对于大于 10 的数字不起作用,我无法弄清楚为什么
int main() {
double n, nq, x, y;
printf("Enter the number you wish to take to the base 10 logarithm:\n");
scanf("%lf", &x);
double hi = 1;
double lo = 0;
double qlo = 1;
double qhi = 10;
for(int i = 0; i <= 1000; i++) {
n = ((lo + hi)/2);
nq = sqrt(qlo * qhi);
if(nq > x) {
hi = n;
qhi = nq;
} else {
lo = n;
qlo = nq;
}
}
y = n;
printf("the logarithm is equal to %lf\n", y);
printf("%lf\n", log10(x)); // to check result
}
在将 qhi
设置为 10 时,您已将结果限制为 10。将 hi
设置为 1 也无济于事。所以任何大于 10 的输入都会 return 值 1.
如果您希望您的函数适用于更大的域,您需要更加明智地选择 hi
、lo
、qlo
和 qhi
.
这接近于一道数学题。您的函数能够为范围 [1:10] 中的任何值 x 计算 log10(x) 的近似值。背后的原理很简单:log10(1) 是 0,log10(10) 是 1,log10(sqrt(a*b)) 是 1/2(log10(a)+log10(b))。
所以你构建了 2 个序列,第一个使用二分法来近似 x,第二个将近似 log10(x).
简单地说,您必须遵守以下约束:1<=x<=10。
通常的写法是x = m 10n 1<=m<10。如果它 >=10(resp <=1),只需将 x 除以(resp。乘以)十,直到它落在正确的范围内。然后你得到平凡的:log10(x) = n + log10(m)。甚至不要尝试负值...
Enter the number you wish to take to the base 10 logarithm:
1234.5678
50 iterations found 3.091514945509
查看以下更改...
#define _CRT_SECURE_NO_WARNINGS
#include <stdio.h>
#include <math.h>
int main()
{
double x, y;
printf("Enter the number you wish to take to the base 10 logarithm:\n");
scanf("%lf", &x);
double hi = 1;
double lo = 0;
double qlo = 1;
double qhi = 10;
/*if (x <= 0) handle exception log undefined for input <= 0*/
double tmp = 0;
while (x > 10)
{
tmp++;
x /= 10;
}
int i;
double n = 0, nprev = -1;
for (i = 0; i <= 1000 && fabs(n - nprev) > 1.0E-15; i++)
{
nprev = n;
n = ((lo + hi) / 2);
double nq = sqrt(qlo * qhi);
if (nq > x)
{
hi = n;
qhi = nq;
}
else
{
lo = n;
qlo = nq;
}
}
y = tmp + n;
printf("%2d iterations found %.12f",i,y);
}