Formatting a string in D - string-formatting

I read on D's documentation that it's possible to format strings with arguments as print statements, such as the following:
float x = 100 / 3.0;
writefln("Number: %.*g", 2, x);
Number: 33.33
However, I'm wondering how I would do this if I just wanted the string equivalent, without printing it. I've looked at the std.format library but that seems way to messy for something I only need to use once. Is there anything a little bit more clear available?

Import std.string or std.format and use the format function.
import std.string;
void main()
{
float x = 100 / 3.0;
auto s = format("Number: %.*g", 4, x);
assert(s == "Number: 33.33");
}

Related

How to calculate this factorial

#include <stdio.h>
int main(){
int n, v;
printf("Please enter a value from 39 to 59: \n");
scanf("%d", &n);
printf("Please enter a value from 3 to 7: \n");
scanf("%d", &v);
}
When I got those values from user, how can I perform this factorial calculation:
n! / ((n-v)! * v!))
I've tried different data types but apparently none can hold the result.
For example: n = 49, v=6. The result is: 13,983,816, but how can I go about getting it?
You're best bet is to ditch the naive factorial implementations, usually based on recursion, and switch to one that returns the natural log of gamma function.
The gamma function is related to factorial: gamma(n) = (n-1)!
Best of all is natural log of gamma, because you can rewrite that expression like this:
ln(n!/(n-v)!v!) = ln(n!) - ln((n-v)!) - ln(v!)
But
(n-v)! = gamma(n-v+1)
n! = gamma(n+1)
v! = gamma(v+1)
So
ln(n!/(n-v)!v!) = lngamma(n+1) - lngamma(n-v+1) - lngamma(v+1)
You can find an implemenation for lngamma in Numerical Recipes.
lngamma returns a double, so it'll fit even for larger values.
It should go without saying that you'll take exp() of both sides to get the original expression you want back.
#duffymo idea looked like too much fun to ignore: use lgamma() from <math.h>.
Results past maybe x=1e15, start to lose the trailing significant digits.. Still fun to be able to get 1000000.0!.
void factorial_expo(double x, double *significand, double *expo) {
double y = lgamma(x+1);
const static double ln10 = 2.3025850929940456840179914546844;
y /= ln10;
double ipart;
double fpart = modf(y, &ipart);
if (significand) *significand = pow(10.0, fpart);
if (expo) *expo = ipart;
}
void facttest(double x) {
printf("%.1f! = ", x);
double significand, expo;
factorial_expo(x, &significand, &expo);
int digits = expo > 15 ? 15 : expo;
if (digits < 1) digits++;
printf("%.*fe%.0f\n", digits, significand, expo);
}
int main(void) {
facttest(0.0);
facttest(1.0);
facttest(2.0);
facttest(6.0);
facttest(10.0);
facttest(69.0);
facttest(1000000.0);
return 0;
}
0.0! = 1.0e0
1.0! = 1.0e0
2.0! = 2.0e0
6.0! = 7.20e2
10.0! = 3.628800e6
69.0! = 1.711224524281441e98
1000000.0! = 8.263931668544735e5565708
In a comment, you've finally said that you don't need exact results.
Just use floating-point. The largest intermediate result you'll need to handle is 59!, which is about 1.3868e80; type double is more than big enough to hold that value.
Write a function like:
double factorial(int n);
(I presume you know how to implement it) and use that.
If you're going to be doing a lot of these calculations, you might want to cache the results by storing them in an array. If you define an array like:
double fact[60];
then you can store the value of N! in fact[N] for N from 0 to 59 -- and you can fill the entire array in about the time it would take to compute 59! just once. Otherwise, you'll be doing several dozen floating-point multiplications and divisions on each calculation -- which is trivial if you do it once, but could be significant if you do it, say, thousands or millions of times.
If you needed exact results, you could use an extended integer library like GNU MP, as others have suggested. Or you could use a language (like Python, for example) that has built-in support for arbitrary-length integers.
Or you could probably perform the multiplications and divisions in an order that avoids overflow; I don't know exactly how to do that, but since n! / ((n-v)! * v!)) is a common formula I strongly suspect that work has already been done.
You can't work with such long numbers as 59! in simple way.
However you can use special C libraries which are working with long numbers bigger than 8 bytes, for example GMP

"-1.#J" : Strange output in C Program

Somethings I should say: this is the first time I make a question in here. Usually, when I'm with a doubt about something, I found it answered somewhere (including I found a lot of answers in this website). But this time, I'm not finding an answer, so if there was, I didn't find and I'm sorry for making a question that has already been made (I know you guys don't like it, but I promise that I've searched).
I came out with this doubt by helping to sove another person's doubt. Well, I'm not sure how to say this in English, but I believe it is: "standard deviation" (Standard Deviation on Wikipedia). That's what the program is about.
A person came with a question how to do this, it wasn't working... I didn't know the formula to calculate the standard deviation, but he gave to me. But the one he gave was wrong. I'll show the code of how the program is: PasteBin of My Standard Deviation Code
It seems to be working now with this way I did, but I'm not sure. I gave this solution to the person who asked my help. Is the program right?
But my real question is not if the program is right. There is this part on the code:
sum += pow(v[i] - m,2);
When he gave me the wrong formula it was:
sum += v[i] - m;
Can you guys compile that wrong code? Depending on the numbers that you put, the output is -1.#J. Why's that? What does this mean?
#include <stdio.h>
#include <math.h>
int main (void)
{
int n = 10, i;
double d, m = 0.0f, sum = 0.0f, v[10];
for (i = 0; i < n; i++)
{
printf ("Inform a real number: ");
scanf ("%lf",&v[i]);
m += v[i];
}
m /= n;
for (i = 0; i < n; i++)
sum += pow(v[i] - m,2);
d = sqrt (sum/(n-1));
printf ("The standard deviation of vector v is = %.2lf\n\n",d);
return 0;
}
1.#J is Microsoft's strange way of displaying infinity. This is a special floating-point value that results from dividing by zero or from numeric overflow.
I can't figure out why you're getting it, though. What inputs are you entering that give you the strange output?
m /= n;this is the average
d = sqrt (sum/(n-1));but why this place use n -1,I think it should be n
now why the output is -1.#j:
This is because the float you input is not right(I mean your input is not a float),example you input ad,I think the output is random if the input is wrong.
If you are not compiling your program in C99/11 mode then the program's behavior is undefined, you can get anything. A double type data is printed by using %f format specifier.
printf ("The standard deviation of vector v is = %.2lf\n\n",d);
^
| Wrong specifier
7.21.6 Formatted input/output functions:
If a conversion specification is invalid, the behavior is undefined.282) If any argument is not the correct type for the corresponding conversion specification, the behavior is undefined.
Also change
double d, m = 0.0f, sum = 0.0f, v[10];
line to
double d, m = 0.0, sum = 0.0, v[10];
m and sum are of double type, no need to put f for forcing that it is a float type.

How to write this function C

Hi I am new to C programming, I am just trying to replace part of my code with a function call but I don't know how to do it properly, please help.
I just want the line d = ... to be equivalent to the line e = ...
#include <stdio.h>
#include <math.h>
double dist(int i, int j, double v[100][2])
{
return sqrt( pow((v[j][0] - v[i][0]),2) + pow((v[j][1] - v[i][1]), 2) )
}
main()
{
double v[100][2], d, e;
v[1][0] = 0;
v[1][1] = 1;
v[2][0] = 1;
v[2][1] = 1;
d = sqrt( pow((v[1][0] - v[2][0]),2) + pow((v[1][1] - v[2][1]), 2) );
e = dist(1,2,v);
printf("\n%f\n",d);
printf("\n%f\n",e);
}
double dist(int i, int j, double (*v)[2])
{
return sqrt( pow((v[j][0] - v[i][0]),2) + pow((v[j][1] - v[i][1]), 2) );
}
d = dist(0,1,v)
Or dist(1,0,v)
Distance between point 0 and point 1 ... Order does not matter.
EDIT: What I have above is a function CALL, as requested. d= is equivalent to e= ... to write another function is quite the waste of code and more importantly, not a realization of what a function is used for. I stick by my answer.
If you wanted the same thing for different types, you can use a macro (not recommended for this case since a decent compiler will inline the function call to Cato's function) but just for educational purposes
#define dist(i,j,v) sqrt(pow((v[j][0]-v[i][0]),2)+pow((v[j][1]-v[i][1]),2))
Just keep in mind that sqrt returns a double, so if you want float or long double returns, you'll need sqrtf or sqrtl.
The advantage to using macros for mathematical "functions" is that they get expanded out into the code prior to compile such that constants can be evaluated into the computation and can sometimes reduce the entire calculation down to a much simpler computation or sometimes even a constant value.
Mike is correct on the mathematical properties, though precision may cause the 2 values to differ slightly (usually this difference is unwanted).

How do I set a value to a variable by passing the variales name in C?

char whatVar[] = "";
float phValue, ecValue, tempValue;
I am not sure if this is possible or not in C. Each of the float values will be set randomly. I would like to set their values depending on what the char whatVar corresponds to. For example, lets say char whatVar[] = "phValue"; How do I point to the variable name inside whatVar to then set the value? I would like to achieve this without using if conditionals or a switch.
Don't; use an array. Tying your program logic to the names of your variables is a horrible idea. Variable names exist to help you as a programmer reason about what the code is doing. Beyond that the do not (and should not) have any significance.
Instead, use a collection where the index/bucket/mapping/whatever has logical meaning. It is very common for beginners to do exactly as you want to do, but it is almost certainly a bad idea. Sounds to me like you want a string -> float map or hash table.
You will have to implement the translation of whatVar onto the actual variable value manually. C language has no such immediate feature.
It can be done by if/switch ladder. Or it can be done by pre-building a table that "projects" (maps) variable names to variable addresses (and, if necessary, types). You will have to manually search through the table. It will still have if's though, unless you develop some sort of [minimal] perfect hashing function for your names (see Steve Jessop's comment).
This is outside of the language specification and I think if this is a feature that you wish to have in the language another language would be of more use to you that has this kind of functionality in it.
The only way I can think of implementing this is by doing some preprocessing tricks, which just seems like a bad idea. With this method you will not have if's in the code it self but some very unmaintainable preprocessing.
why not ?
if(strcmp(whatVar, "phValue") == 0)
{
phvalue = 3; //some value
}
and so on and so forth.
Edit : if the ifs and the switch is not desired then we can use some sort of stl map ing between the string representations as the keys and their variables as the values.
If you really really want to do this, you can use the dlsym function (as long as the variables you are accessing are global). Here's a quick example:
#include <dlfcn.h>
#include <stdlib.h>
#include <stdio.h>
float phValue, ecValue, tempValue;
int main(int argc, char *argv[]) {
int i;
phValue = 0;
ecValue = 0;
tempValue = 0;
printf("Before:\n");
printf("\tphValue = %f\n", phValue);
printf("\tecValue = %f\n", ecValue);
printf("\ttempValue = %f\n", tempValue);
for(i = 1; i < argc; i += 2) {
float *varptr = (float *)dlsym(RTLD_MAIN_ONLY, argv[i]);
*varptr = atof(argv[i+1]);
}
printf("\nAfter:\n");
printf("\tphValue = %f\n", phValue);
printf("\tecValue = %f\n", ecValue);
printf("\ttempValue = %f\n", tempValue);
}
And a demo:
% gcc varname.c -ldl
% ./a.out phValue 12.1 tempValue 4.3 ecValue 2.2
Before:
phValue = 0.000000
ecValue = 0.000000
tempValue = 0.000000
After:
phValue = 12.100000
ecValue = 2.200000
tempValue = 4.300000

how to numerically integrate a variable that is being calculate in the program as a pointer (using e.g. trapezoidal rule) in c language

I have a code, that was not made by me.
In this complex code, many rules are being applied to calculate a quantity, d(x). in the code is being used a pointer to calculate it.
I want to calculate an integral over this, like:
W= Int_0 ^L d(x) dx ?
I am doing this:
#define DX 0.003
void WORK(double *d, double *W)
{
double INTE5=0.0;
int N_X_POINTS=333;
double h=((d[N_X_POINTS]-d[0])/N_X_POINTS);
W[0]=W[0]+((h/2)*(d[1]+2.0*d[0]+d[N_X_POINTS-1])); /*BC*/
for (i=1;i<N_X_POINTS-1;i++)
{
W[i]=W[i]+((h/2)*(d[0]+2*d[i]+d[N_X_POINTS]))*DX;
INTE5+=W[i];
}
W[N_X_POINTS-1]=W[N_X_POINTS-1]+((h/2)*(d[0]+2.0*d[N_X_POINTS-1]+d[N_X_POINTS-2])); /*BC*/
}
And I am getting "Segmentation fault". I was wondering to know if, I am doing right in calculate W as a pointer, or should declare it as a simple double? I guess the Segmentation fault is coming for this.
Other point, am I using correctly the trapezoidal rule?
Any help/tip, will very much appreciate.
Luiz
I don't know where that code come from, but it is a lot ugly and has some limits hard-encoded (333 points and increment by 0.003). To use it you need to "sample" properly your function and generate pairs (x, f(x))...
A possible clearer solution to your problem is here.
Let us consider you function and let us suppose it works (I believe it does't, it's a really obscure code...; e.g. when you integrate a function, you expect a number as result; where's this number? Maybe INTE5? It is not given back... and if it is so, why the final update of the W array? It's useless, or maybe we have something meaningful into W?). How does would you use it?
The prototype
void WORK(double *d, double *W);
means the WORK wants two pointers. What these pointers must be depends on the code; a look at it suggests that indeed you need two arrays, with N_X_POINTS elements each. The code reads from and writes into array W, and reads only from d. The N_X_POINTS int is 333, so you need to pass to the function arrays of at least 333 doubles:
double d[333];
double W[333];
Then you have to fill them properly. I thought you need to fill them with (x, f(x)), sampling the function with a proper step. But of course this makes no too much sense. Already said that the code is obscure (now I don't want to try to reverse engineering the intention of the coder...).
Anyway, if you call it with WORK(d, W), you won't get seg fault, since the arrays are big enough. The result will be wrong, but this is harder to track (again, sorry, no "reverse engineering" for it).
Final note (from comments too): if you have double a[N], then a has type double *.
A segmentation fault error often happens in C when you try to access some part of memory that you shouldn't be accessing. I suspect that the expression d[N_X_POINTS] is the culprit (because arrays in C are zero-indexed), but without seeing the definition of d I can't be sure.
Try putting informative printf debugging statements before/after each line of code in your function so you can narrow down the possible sources of the problem.
Here's a simple program that integrates $f(x) = x^2$ over the range [0..10]. It should send you in the right direction.
#include <stdio.h>
#include <stdlib.h>
double int_trapezium(double f[], double dX, int n)
{
int i;
double sum;
sum = (f[0] + f[n-1])/2.0;
for (i = 1; i < n-1; i++)
sum += f[i];
return dX*sum;
}
#define N 1000
int main()
{
int i;
double x;
double from = 0.0;
double to = 10.0;
double dX = (to-from)/(N-1);
double *f = malloc(N*sizeof(*f));
for (i=0; i<N; i++)
{
x = from + i*dX*(to-from);
f[i] = x*x;
}
printf("%f\n", int_trapezium(f, dX, N));
free(f);
return 0;
}

Resources