Getting the formatting right with sprintf() - c

I'm trying to get some formatting done in my sprintf statement, but it doesn't seem to work as I expect. Here is the line:
n = sprintf(buffer, "x = %d.%d, y = %d.%d, z = %d.%d \n", x1, x2, y1, y2, z1, z2);
In that printout x1 is the whole part of the number, and x2 is the fractional part. All would be well, except I need to pad x2, y2, and z2 to always be 2 digits - meaning I need to pad with leading zeros.
With examples that I see online it seems like doing this should work:
n = sprintf(buffer, "x = %d.%02d, y = %d.%02d, z = %d.%02d \n", x1, x2, y1, y2, z1, z2);
However, that instead produces something like this:
x = 2.2d, y = 37.2d, z = 2.2d
The 37 above is actually x2, and it apparently got shifted over in place of y1. I tried putting brackets around the '02', but that doesn't do anything either.
I have tried splitting up the period too like this: (but that didn't work)
n = sprintf(buffer, "x = %d. %02d, y = %d. %02d, z = %d. %02d \n", x1, x2, y1, y2, z1, z2);
I'm not really sure what's wrong... I'd appreciate any help. This isn't particularly vital to do in sprintf (I could theoretically write some 'if' statements and get it working that way), but it'd be nice.
Thanks!

This is a sample code and output.
float x1 = 10.12222;
float y1 = 20.23333;
float z1 = 30.34444;
int xi = 10;
int yi = 20;
int zi = 30;
int x0 = 5;
int y0 = 5;
int z0 = 5;
int xl = 10;
int yl = 10;
int zl = 10;
char chr[512];
printf("x = %5.2f, y = %5.2f, z = %5.2f\n", x1, y1, z1);
printf("x = %10d, y = %10d, z = %10d\n", xi, yi, zi);
printf("x = %010d, y = %010d, z = %010d\n", xi, yi, zi);
printf("x = %-10d, y = %-10d, z = %-10d\n", xi, yi, zi);
printf("x = %10.5d, y = %10.5d, z = %10.5d\n", xi, yi, zi); // DYNAMIC
/* Dynamic formatting of DYNAMIC commented line*/
sprintf(chr, "Dynamic: x = %%%d.%dd, y = %%%d.%dd, z = %%%d.%dd\n",
xl, x0, yl, y0, zl, z0);
printf(chr, xi, yi, zi);
The output will be like this.
x = 10.12, y = 20.23, z = 30.34
x = 10, y = 20, z = 30
x = 0000000010, y = 0000000020, z = 0000000030
x = 10 , y = 20 , z = 30
x = 00010, y = 00020, z = 00030
Dynamic: x = 00010, y = 00020, z = 00030
%x.yd means,
x - Total characters for the integer.
y - Padding with 0s within that length.
%10.5d will give following results for 10, 100, 1000, 10000, 100000, 100000
bbbbbbbbbb => Spaces
00010
00100
01000
10000
100000
1000000
I hope this helps for your formatting.

Related

Is there some way to have y = k*m but in integers only?

I'm trying to write out pixles on a LCD. I'm plotting them at X, Y coordinates and I'm using this code:
void SSD1306_draw_line(uint8_t x0, uint8_t x1, uint8_t y0, uint8_t y1){
uint8_t k = (x1 - x0)/(y1 - y0);
uint8_t y = y0;
for(uint8_t x = x0; x < x1; x++){
pixel(x, y, true);
y += k;
}
}
The problem where is that if k becomes a decimal number e.g 1.98, then k will still 1. If k = 2.01, then k = 2 due to the uint8_t datatype.
Assume that we are going to plot the line (0,0), (40, 20) {x,y}.
Sure, now k will be 2. That works!
But assume that if we plot the line (0,0), (35, 20) {x,y}.
Now k will be a float number of 1.75. This will not work for me.
Is there a way to find a better k?
I have tried this, but the line does not follow the coordinates.
void SSD1306_draw_line(uint8_t x0, uint8_t x1, uint8_t y0, uint8_t y1){
float k = 0;
if(y1 > x1){
k = (y1 - y0)/(x1 - x0);
}else{
k = (x1 - x0)/(y1 - y0);
}
float y = y0;
for(uint8_t x = x0; x < x1; x++){
pixel(x, (uint8_t) y, true);
y += k;
}
}
Instead of attempting FP math, research Bresenham's line algorithm for an all integer solution.
Untested code:
void SSD1306_draw_line(uint8_t x0, uint8_t x1, uint8_t y0, uint8_t y1) {
int dx = x1 - x0;
int dy = y1 - y0;
int D = 2*dy - dx;
int y = y0;
// code still needs work when x0 > x1 or |dy| > |dx|
for (int x = x0; x <= x1; x++) {
pixel(x,y,true);
if (D > 0) {
y++;
D = D - 2*dx;
}
D = D + 2*dy;
}
}
You were on the right path with changing k and y to data type float.
But in addition to that, you need to make sure that the right hand side of
k = (y1 - y0)/(x1 - x0);
will be a float value, too. Currently, since only integral values are involved, the result of the expression on the right hand side will be integral. So k will never receive any fractional part.
To "enforce" floating point division, it is sufficient that one of the operands is of type float. You can achieve this by an explicit cast. Write, for example:
k = ((float)(y1 - y0))/(x1 - x0);

Scanf in struct containing 'double' array doesnt work?

So I have to program a scalarproduct ((x1*y1)+(x2*y2)) with the use of structs and scanf.
However my program just skips y1 and counts both y1 and x2 as the same number even though I type in completely different numbers??
I did the following:
struct _point2d
{
double x[1]; // this means x1 is x[0] and x2 is x[1]
double y[1];
};
double PscalarProduct( double a, double b, double c, double d )
{
printf("The scalar product ((x1*y1) + (x2*y2)) (whereas x1 = %lf,
y1 = %lf, x2 = %lf, y2 = %lf) is %lf\n", a, b, c, d, (( a*b ) + ( c*d )) );
}
int main()
{
struct _point2d Vector;
Vector.x[1];
Vector.y[1];
printf("Enter x1 and y1 \n");
scanf("%lf", &(Vector.x[0]));
scanf("%lf", &(Vector.y[0]));
printf("Enter x2 and y2 \n");
scanf("%lf", &(Vector.x[1]));
scanf("%lf", &(Vector.y[1]));
PscalarProduct(Vector.x[0], Vector.y[0], Vector.x[1], Vector.y[1]);
return 0;
}
However if i run the program with the numbers 1[=x1] 2[=y1] 3[=x2] 4[=y2] I receive this text:
The scalar product ((x1*y1) + (x2*y2)) (whereas x1 = 1.000000, y1 = 3.000000, x2 = 3.000000, y2 = 4.000000) is 15.000000
How can this be that y1 and x2 are the same numbers??? y1 should be the number 2.00000.
The struct members x and y arrays can hold only one element each. But you are reading 2 elements as input.
In C, array index ranges from 0 to N-1. Your code has undefined behaviour due to out of bounds access.
Increase the array size:
struct _point2d
{
double x[2]
double y[2];
};

Quaternion to euler angles and euler angles to quaternion in C

I have been writing this code for checking the euler angles and quaternions, but it is not run correcly (or maybe I do not understand the rotations):
#include <stdio.h>
#include <math.h>
#define DR2D (180 / M_PI)
#define DD2R (M_PI / 180)
int main(int argc, char** argv)
{
float x, y, z;
x = 0 * DD2R;
y = 0 * DD2R;
z = 180 * DD2R;
printf("x=%f y=%f z=%f\n", x, y, z);
float sx = sin(x / 2);
float sy = sin(y / 2);
float sz = sin(z / 2);
float cx = cos(x / 2);
float cy = cos(y / 2);
float cz = cos(z / 2);
float qx, qy, qz, qw;
printf("sx = %f sy = %f sz = %f cx = %f cy = %f cz = %f\n", sx, sy, sz, cx, cy, cy);
qx = cx*cy*sz + sx*sy*cz;
qy = sx*cy*cz + cx*sy*sz;
qz = cx*sy*cz - sx*cy*sz;
qw = cx*cy*cz - sx*sy*sz;
printf("Quaternion -> (%f, %f, %f, %f)\n", qx, qy , qz , qw);
//------------------------------------------------------------------
float sqw = qw*qw;
float sqx = qx*qx;
float sqy = qy*qy;
float sqz = qz*qz;
float unit = sqx + sqy + sqz + sqw; // if normalised is one, otherwise is correction factor
float test = qx*qy + qz*qw;
if (test > 0.499*unit) { // singularity at north pole
x = 2 * atan2(qx,qw);
y = M_PI/2;
z = 0;
}
else if (test < -0.499*unit) { // singularity at south pole
x = -2 * atan2(qx,qw);
y = -M_PI/2;
z = 0;
}
else {
x = atan2(2*qy*qw-2*qx*qz , sqx - sqy - sqz + sqw);
y = asin(2*test/unit);
z = atan2(2*qx*qw-2*qy*qz , -sqx + sqy - sqz + sqw);
}
printf("recover euler x=%.2f y=%.2f z=%.2f\n",
x * DR2D, y * DR2D, z * DR2D);
}
Because the output is very weird:
For example: x 180º y 90º z 90º
x=3.141593 y=1.570796 z=1.570796
sx = 1.000000 sy = 0.707107 sz = 0.707107 cx = -0.000000 cy = 0.707107 cz = 0.707107
Quaternion -> (0.500000, 0.500000, -0.500000, -0.500000)
reconversion euler x=270.00 y=90.00 z=0.00
Or for example x 90º y 90º z 90º
x=1.570796 y=1.570796 z=1.570796
sx = 0.707107 sy = 0.707107 sz = 0.707107 cx = 0.707107 cy = 0.707107 cz = 0.707107
Quaternion -> (0.707107, 0.707107, 0.000000, 0.000000)
recover euler x=180.00 y=90.00 z=0.00
The algorithm you use has a domain that lies in the interval [0,pi/2) only, the first quadrant. Or, because you want the input to be in degrees, between 0 (zero) inclusive and 90 degrees exclusive.

C loop with steps smaller than 1

So I'm wondering, how do I make sure that all steps in a loop are performed if the step size is smaller than 1? Take this loop for instance:
for (float y, x = -1.0; x <= 1.0; x += 0.1) {
y = (4*x*x*x) + (3*x*x) + (5*x) - 10;
printf("x = %.2f, y = %.2f\n", x, y);
}
Output:
x = -1.00, y = -16.00
x = -0.90, y = -14.99
x = -0.80, y = -14.13
x = -0.70, y = -13.40
x = -0.60, y = -12.78
x = -0.50, y = -12.25
x = -0.40, y = -11.78
x = -0.30, y = -11.34
x = -0.20, y = -10.91
x = -0.10, y = -10.47
x = 0.00, y = -10.00
x = 0.10, y = -9.47
x = 0.20, y = -8.85
x = 0.30, y = -8.12
x = 0.40, y = -7.26
x = 0.50, y = -6.25
x = 0.60, y = -5.06
x = 0.70, y = -3.66
x = 0.80, y = -2.03
x = 0.90, y = -0.15
I intend the loop to also run for x = 1, but as you can see it doesn't do that. I've heard that it's not safe to use floats as loop counters, as the float precision isn't exact. The fact that I'm using a float variable as the loop counter is probably the cause of my problem. So what solutions are there to my problem? Thanks in advance for your kind responses!
The problem, as you noted, is that you shouldn't use floats as loop counters. So multiply everything by 10 and use integers:
for (int x = -10; x <= 10; ++x) {
float y = (0.004*x*x*x) + (0.03*x*x) + (0.5*x) - 10;
printf("x = %.2f, y = %.2f\n", 0.1*x, y);
}
Produces:
x = -1.00, y = -16.00
x = -0.90, y = -14.99
x = -0.80, y = -14.13
...
x = 0.90, y = -0.15
x = 1.00, y = 2.00
as expected.
Perhaps even better: logically separate your loop variable from the meaningful stuff.
for(int i = -10; i <= 10; ++i) {
float x = 0.1 * i;
float y = (4*x*x*x) + (3*x*x) + (5*x) - 10;
printf("x = %.2f, y = %.2f\n", x, y);
}

calculate co-ordinates of lower left corner of minimum enclosing rectangle and length and width provided 2 rectangle

Input and Output Format:
The 1st line of the input consists of 4 integers separated by a space that correspond to x, y, l and w of the first rectangle.
The 2nd line of the input consists of 4 integers separated by a space that correspond to x, y, l and w of the second rectangle.
Output consists of 4 integers that correspond to x, y, l and w of the Union rectangle.
Sample Input :
3 8 1515
2 6 10 10
Sample Output:
2 6 16 17
here is my code
it gets validated for some test cases and it is not accepted when I submit it.
I'm trying this on an online coding website.
here is my code.
#include<stdio.h>
#include<math.h>
int main()
{
int x1,y1,x2,y2,l1,w1,l2,w2,x3,y3,l3,w3;
scanf("%d %d %d %d",&x1,&y1,&l1,&w1);
scanf("\n%d %d %d %d",&x2,&y2,&l2,&w2);
if(x1<x2)
x3=x1;
else
x3=x2;
if(y1<y2)
y3=y1;
else
y3=y2;
if(x1==x2)
{
if(l1<l2)
w3=l2;
else
w3=l1;
}
if(y1==y2)
{
// printf("inp");
if(w1<w2)
{
w3=w2;
//printf("%d",w3);
}
else
{
w3=w1;
}
}
if(x1<x2)
l3=l2+fabs(x1-x2);
else if(x2<x1)
l3=l1+fabs(x1-x2);
if(y1<y2)
w3=w2+fabs(y1-y2);
else if(y2<y1)
w3=w1+fabs(y1-y2);
printf("%d ",x3);
printf("%d ",y3);
printf("%d ",l3);
printf("%d",w3);
return 0;
}
if anyone have alternative logic then tell me.
#include<stdio.h>
int main()
{
int x1, y1, x2, y2, l1, w1, l2, w2;
scanf("%d %d %d %d",&x1,&y1,&l1,&w1);
scanf("\n%d %d %d %d",&x2,&y2,&l2,&w2);
int min_x = x1 < x2 ? x1 : x2;
int min_y = y1 < y2 ? y1 : y2;
int max_x = (x1+w1) > (x2+w2) ? (x1+w1) : (x2+w2);
int max_y = (y1+l1) > (y2+l2) ? (y1+l1) : (y2+l2);
int max_w = max_x - min_x;
int max_l = max_y - min_y;
printf("%d %d %d %d", min_x, min_y, max_l, max_w);
return 0;
}
This is assuming that your widths are in the x direction and your lengths are in the y direction. If it is the other way, it should not be too hard to change.
I have faced the same problem in the online course...
here is my link to the question.
union of two rectangles.write a program to find the smallest possible rectangle enclosing the 2 given rectangles
and my program which is working and is accepted without any error or "wrong answer"..
#include<stdio.h>
int main() {
int x1, x2, y1, y2, l1, l2, w1, w2, xmax, xmin, ymax, ymin;
scanf(“%d %d %d %d\n”,&x1,&y1,&l1,&w1);
scanf(“%d %d %d %d\n”,&x2,&y2,&l2,&w2);
xmin = x1 < x2 ? x1 : x2;
ymin = y1 < y2 ? y1 : y2;
int b = x1 + l1;
int c = x2 + l2;
xmax = b > c ? b : c;
int d = y1 + w1;
int e = y2 + w2;
ymax = d > e ? d : e;
int l = xmax - xmin;
int w = ymax - ymin;
printf(“%d %d %d %d”,xmin,ymin,l,w);
return 0;
}

Resources