How do I write a function for this in C language?
y = 20 ln (x + 3) ?
How do I write the ln function?
#include <math.h>
double fun(double x)
{
return 20 * log( x + 3 ); //base-e logarithm!
}
//usage
double y = fun(30);
For base-10 logarithm, use log10().
double myfunction(int x){
return (20* log(x+3) );
}
?
And you call it :
double y = myfunction(yourX);
#include <math.h>
double function(double x)
{
double y = 20 * log(x + 3.0);
return y;
}
The log function in the c library is performs a natural logarithm ('ln'). See this for more details: CPlusPlus - log
Although the question is tagged C++, questioner is asking for a C implementation:
#include <math.h>
double myFunction(double x) {
return 20.0 * log(x + 3.0);
}
Related
So I am trying to round DOWN to 2 decimal places in C - EDIT: I actually need to change the value, not just display it to 2 decimals.
For example:
double x = 0.1234;
x = 0.12;
double y = 3.14159;
y = 3.14;
Is the an integrated function in <math.h> similar to floor(), or is there another way to do this?
Well I need to value to change so I used x = (double)((int)(x*100))/100;
This works, but you are limited to a relatively low range, i.e: 123456789 * 100 overflows.
Check if modf helps:
#include <stdio.h>
#include <math.h>
double dec2(double number)
{
double fractpart, intpart;
fractpart = modf(number, &intpart);
return intpart + round(fractpart * 100) * 0.01;
}
int main(void)
{
printf("%f\n", dec2(0.1234));
printf("%f\n", dec2(3.14159));
return 0;
}
Output:
0.120000
3.140000
If you want to display a float or double with 2 decimal places, specify a precision of 2 when using the %f format specifier.
printf("x=%.2f", x);
The teacher asks to remove the pi subtraction cycle in the main function. I don’t know how to write the program so that the correct results will come out for any values.
#include <stdio.h>
#include <math.h>
double sinus(double x);
int main(void) {
double a, x;
scanf("%le", & x);
a = x;
while (fabs(x) > 2 * (M_PI)) {
x = fabs(x) - 2 * (M_PI);
}
if (a > 0)
a = sinus(x);
else a = (-1) * sinus(x);
printf("%le", (double) a);
return 0;
}
double sinus(double x) {
double sum = 0, h, eps = 1.e-16;
int i = 2;
h = x;
do {
sum += h;
h *= -((x * x) / (i * (i + 1)));
i += 2;
}
while (fabs(h) > eps);
return sum;
return 0;
}
#include <stdio.h>
#include <math.h>
double sinus(double x);
int main(void)
{
double a,x;
scanf("%le",&x);
a=x;
x=fmod(fabs(x),2*(M_PI));
if(a>0)
a=sinus(x);
else a=(-1)*sinus(x);
printf("%le",(double)a);
return 0;}
double sinus(double x)
{
double sum=0, h, eps=1.e-16; int i=2;
h=x;
do{
sum+=h;
h*=-((x*x)/(i*(i+1)));
i+=2;}
while( fabs(h)>eps );
return sum;
return 0;
}
… how to write the program so that the correct results will come out for any values.
OP's loop is slow with large x and an infinfite loop with very large x:
while (fabs(x) > 2 * (M_PI)) {
x = fabs(x) - 2 * (M_PI);
}
A simple, though not high quality solution, is to use fmod() in the function itself. #Damien:
#ifndef M_PI
#define M_PI 3.1415926535897932384626433832795
#endif
double sinus(double x) {
x = fmod(x, 2*M_PI); // Reduce to [-2*M_PI ... 2*M_PI]
...
Although function fmod() is not expected to inject any error, the problem is that M_PI (a rational number) is an approximation of π, (an irrational number). Using that value approximation injects error especially x near multiplies of π. This is likely OK for modest quality code.
Good range reduction is a problem as challenging as the trigonometric functions themselves.
See K.C. Ng's "ARGUMENT REDUCTION FOR HUGE ARGUMENTS: Good to the Last Bit" .
OP's sinus() should use additional range reduction and trigonometric properties to get x in range [-M_PI/4 ... M_PI/4] (example) before attempting the power series solution. Otherwise, convergence is slow and errors accumulate.
I have a program in C++ (compiled using g++). I'm trying to apply two doubles as operands to the modulus function, but I get the following error:
error: invalid operands of types 'double' and 'double' to binary 'operator%'
Here's the code:
int main() {
double x = 6.3;
double y = 2;
double z = x % y;
}
The % operator is for integers. You're looking for the fmod() function.
#include <cmath>
int main()
{
double x = 6.3;
double y = 2.0;
double z = std::fmod(x,y);
}
fmod(x, y) is the function you use.
You can implement your own modulus function to do that for you:
double dmod(double x, double y) {
return x - (int)(x/y) * y;
}
Then you can simply use dmod(6.3, 2) to get the remainder, 0.3.
Use fmod() from <cmath>. If you do not want to include the C header file:
template<typename T, typename U>
constexpr double dmod (T x, U mod)
{
return !mod ? x : x - mod * static_cast<long long>(x / mod);
}
//Usage:
double z = dmod<double, unsigned int>(14.3, 4);
double z = dmod<long, float>(14, 4.6);
//This also works:
double z = dmod(14.7, 0.3);
double z = dmod(14.7, 0);
double z = dmod(0, 0.3f);
double z = dmod(myFirstVariable, someOtherVariable);
Say I have a high floating point number... 1345.23
I want to reduce it by 2*PI until it stays between -PI and +PI so I'd do:
#define PI 3.14159265358f
#define TWO_PI 6.28318530718f
float a = 1345.23f;
while (a > PI) a -= TWO_PI;
Do you know a fastest method?
With this code you will enter in the loop just 1 time (you can delate it adding just a more a -= TWO_PI
#include <stdio.h>
#define PI 3.14159265358f
#define TWO_PI 6.28318530718f
int main(void) {
float a = 1345.23f;
float b = 1345.23 - PI;
int c = b/TWO_PI;
a -= c*TWO_PI;
int i = 0;
while (a > PI){
a -= TWO_PI;
printf("%d",i++);
}
printf("\na : %f",a);
}
OUTPUT:
0
a : 0.628314
While your code will do the cicle :
214 times
BETTER CODE:
#include <stdio.h>
#define PI 3.14159265358f
#define TWO_PI 6.28318530718f
#define INV_TWO_PI 0.15915494309189533
int main(void) {
double a = 1345.23;
if(a > PI){
double b = a - PI; // you get the distance between a and PI
// int c = b/TWO_PI; // you get the integer part
int c = b * INV_TWO_PI; // the same as above using multiplication
a -= (c+1)*TWO_PI; // you just subtract c+1 times TWO_PI
// c+1 cause you want come in the range [-PI,PI]
}
}
Not the fastest, but the shortest code:
y = asin(sin(a));
Assuming that your code has to do with phase wrapping in radians, so that values between PI and TWO_PI can map between -PI and 0.0 a simple and fast solution would be:
double a = 1345.23;
double b = TWO_PI;
double c = (fmod(a,b) > PI ? fmod(a,b) - b : fmod(a,b));
After accept answer
To quickly reduce between -PI and PI, simply use remquof();
#include <math.h>
#include <stdio.h>
float reduce_radian(float x) {
static const float pi2 = 6.283185307179586476925286766559f;
int n;
return remquof(x, pi2, &n);
}
int main(void) {
printf("x % .10e\ty % .10e\n", 1e-30, reduce_radian(1e-30));
for (float x = 0.0f; x <= 4.0f; x += 1.0f) {
printf("x % .10f\ty % .10f\n", -x, reduce_radian(-x));
printf("x % .10f\ty % .10f\n", x, reduce_radian(x));
}
}
Output
x 1.0000000000e-30 y 1.0000000032e-30
x -0.0000000000 y -0.0000000000
x 0.0000000000 y 0.0000000000
x -1.0000000000 y -1.0000000000
x 1.0000000000 y 1.0000000000
x -2.0000000000 y -2.0000000000
x 2.0000000000 y 2.0000000000
x -3.0000000000 y -3.0000000000
x 3.0000000000 y 3.0000000000
x -4.0000000000 y 2.2831854820
x 4.0000000000 y -2.2831854820
To understand why this is not the best precise answer, is a deep subject.
See K.C. Ng's "ARGUMENT REDUCTION FOR HUGE ARGUMENTS: Good to the Last Bit"
How is the fmod function implemented?
I tried the following:
#include <stdio.h>
#include <math.h>
float floatMod(float a, float b)
{
return (a/b - floor(a/b));
}
int main()
{
printf("%f\n", fmod(18.5,4.2));
printf("%f\n", floatMod(18.5,4.2));
}
But the output is not the same...
Your fmod function should be:
float floatMod(float a, float b)
{
return (a - b * floor(a / b));
}
LIVE DEMO
UPDATE 7-Feb-2020
As pointed out by #s3cur3 et al in the comments below, the implementation above does not give correct results (as in matching the standard library fmod() function) when the first argument is negative. Using the definition in this answer a more correct implementation would be:
float floatMod(float a, float b)
{
return a - (round(a / b) * b);
}
LIVE DEMO
Apparently the update is broken too (see comment from #Bernard below) - I would delete the answer but it's been accepted, so I'll try and get back to it and fix it in the near future.
A correct implementation of fmod function in C/C++ is:
#include <iostream>
using namespace std;
#include <math.h> //for trunc()
double MyFmod(double x, double y) {
return x - trunc(x / y) * y;
}
//test it
int main()
{
double values[13] = {-10.9, -10.5, -10.4, -0.9, -0.5, -0.1, 0, 0.1, 0.5, 0.9, 10.4, 10.5, 10.9};
for (size_t i = 0; i < 12; ++i)
cout << fmod(values[i], 3.0) <<" "<< MyFmod(values[i], 3.0) << endl;
for (size_t i = 0; i < 12; ++i)
cout << fmod(values[i], -3.0) <<" "<< MyFmod(values[i], -3.0) << endl;
return 0;
}
A correct implementation of fmod function in Java is:
//trunc() implementation in Java:
double truncate(double x) {
return x < 0 ? -Math.floor(-x) : Math.floor(x);
//or return x < 0 ? Math.ceil(x) : Math.floor(x);
}
double MyFmod(double x, double y) {
return x - truncate(x / y) * y;
}
One also could use fma instruction to improve precision (although this will work correctly only when result of trunc(x/y) is computed exactly):
C/C++: fma(trunc(x / y), -y, x);
Java: Math.fma(truncate(x / y), -y, x);
Note: When the accuracy of double is not enough, all the above implementations are probably inferior to the compiler's math library. In my compiler, std::fmod(1e19, 3) computes 1.0 (accurate result), while MyFmod with same arguments, returns -512.