« first day (252 days earlier)      last day (350 days later) » 

06:27
@JohnRennie: Hi sir :-)
I got fascinated by gyroscopes again.
I'm thinking of making a motor-powered gyroscope to see how it reacts to earth's rotation. Do you have any experience in making one, sir?
@GuruVishnu I don't I'm afraid.
No worries!
I guess you are in effect making an inertial guidance system ...
Hmm... I've heard about their applications in spacecrafts. I was thinking of creating an analog clock using a gyroscope.
Ah, to tell the time from the angle relative to the (rotating) earth frame
That's a cool idea :-)
06:35
:-)
One thing which troubles me is: if I try to rotate the disc using a motor, then the motor unit along with the gimbal would start rotating in the opposite direction. I don't want that to happen.
I've no idea how you power a gyroscope. It must be fairly routine since that's what inertial guidance systems do.
I think seeing the blueprints of inertial units would help. Thank you.
 
1 hour later…
08:02
@JohnRennie: Hi sir :-)
Are you free now?
@GuruVishnu hi, yes I'm free :-)
Ok sir. Could you please tell whether the following expression is a good way to find the units place digit?:
r = (c/10-floor(c/10))*10;
For some reason, this doesn't work well for number 34:
In C/C++ ?
In C++ sir. Here's the full code:
#include<iostream>
#include<math.h>

using namespace std;

int main()
{
	double a = 1, b = 1, c = 0, sum=0;
	int r = 0;
	do
	{
		c = a + b;
		a = b;
		b = c;
		r = (c/10-floor(c/10))*10;
		cout << r<<"\t"<<c<<endl;
		if (r % 2 == 0)
			sum += c;
	} while (c < 55);
	cout << sum;
}
One of the things you have to be careful of in any language is that decimals cannit be exactly represented in binary so you can get rounding errors.
I'd guess that is what happens with 34. You'd have to go through the individual operations in your expression to find out where the rounding error is creeping in.
Fortunately there is a far simpler solution. I would use:
r = ((int) c) % 10;
08:09
Thank you sir. I agree using modulo is simpler, the problem is the number c can be as large as 4 million and can lead to data loss when type casted to int :-(
Is there any workaround to find the unit place digit for type double?
r = ((long long unsigned) c) % 10;
long long unsigned can be up to 18,446,744,073,709,551,615
Thank you very much sir. Now it works:
Or you could use floor(c) % 10
But how can we use a non-integral operand (of type long long) in the modulo operator?
I thought only (integer)%(integer) is valid.
The (long long unsigned) cast converts it to an integer type, so you do have integers both sides of the modulo operator.
@GuruVishnu long long unsigned is an integer type
08:17
Ah. Fine sir. Thank you :-)
I wonder what was causing the original rounding error ...
@JohnRennie A small doubt, how can this give us the unit place? c is already a whole number.
So, floor(c)=c and c%10 is invalid as c is of type double. Maybe if I delare it as long long unsigned, it would solve all the problem.
Any integer mod 10 gives the rightmost digit ...
Do you mean how does the cast to long long unsigned work?
No sir. I can understand that we're explicitly typecasting the double output to long long unsigned. I was wondering how the double value of c could be used in the modulo operator to give us the unit digit. Especially, I was referring to the expression floor(c) % 10.
Is it something like the range of the function floor() is of the type integer?
Ah, yes, you can't use floor(c) % 10 as that will complain the the left side is not an integer type.
You'd have to use ((long long unsigned) floor(c)) % 10 and in that case the call to floor() is unnecessary.
08:30
Ok sir. Thank you. Although, I must be thinking of an efficient way to solve this problem. This is just the straight forward approach.
Aha! Re your original approach, try this:
int main()
{
  long long unsigned r;
  double c, d;

  c = 34;

  d = (c/10-floor(c/10))*10;
  printf("d - 4 = %e\n", d - 4.0);

  r = (c/10-floor(c/10))*10;
  cout << r<<"\t"<<c<<endl;

  return 0;
}
I get:
D:\rhs\c>rat
d - 4 = -8.881784e-16
3       34
So the rounding errors are making d very slightly less than 4.
Oh! You were analysing why the first method went wrong? I simply changed the data type of all the variables to long long unsigned :-)
I didn't expect that rounding errors would creep in.
Yes, I was curious where the error was coming from.
As a general rule, whenever you are using floating point variables you need to bear in mind that there will be rounding errors.
Ok sir. Good to know. Thank you. I'll be careful from now on.
But here, I'm unable to understand why we would get such errors as we're just dividing by 10. Moreover, before assigning this to the integer variable, we're multiplying with 10 again. Could you explain why this is so sir?
OK try:
  d = c/10-floor(c/10);
  printf("d - 4 = %e\n", d - 0.4);
I get:
d - 4 = -1.110223e-16
floor(c/10) will be exactly equal to 3 because floor() is guaranteed to return an integer, so it must be that c/10 isn't exactly equal to 3.4.
Though:
  d = c/10;
  printf("d - 4 = %e\n", d - 3.4);
prints:
0.000000e+00
08:46
So, is it a problem with the floor function?
Try:
  d = c/10-3;
  printf("d - 0.4 = %e\n", d - 0.4);
I get:
d - 0.4 = -1.110223e-16
Yes, so it isn't the floor function because replacing it with the integer 3 still gives the problem.
I think the rounding error comes when we do arithmetic between a float and a pure integer.
d = c/10-1.0 and d = c/10-2.0 both give an exact result, but d = c/10-3.0 and d = c/10-4.0 do not.
Try:
  d = c/10-1.0;
  printf("c/10-1.0 gives %e\n", d - 2.4);
  d = c/10-2.0;
  printf("c/10-2.0 gives %e\n", d - 1.4);
  d = c/10-3.0;
  printf("c/10-3.0 gives %e\n", d - 0.4);
  d = c/10-4.0;
  printf("c/10-4.0 gives %e\n", d + 0.6);
Now it gets weird. I tried:
  c = 34;
  d = c/10-1.0;
  printf("c/10-1.0 gives %e\n", d - 2.4);
  d = c/10-2.0;
  printf("c/10-2.0 gives %e\n", d - 1.4);
  d = c/10-3.0;
  printf("c/10-3.0 gives %e\n", d - 0.4);
  d = c/10-4.0;
  printf("c/10-4.0 gives %e\n", d + 0.6);
  d = c/10-5.0;
  printf("c/10-5.0 gives %e\n", d + 1.6);
  d = c/10-6.0;
  printf("c/10-6.0 gives %e\n", d + 2.6);
  d = c/10-7.0;
  printf("c/10-7.0 gives %e\n", d + 3.6);
  d = c/10-8.0;
  printf("c/10-8.0 gives %e\n", d + 4.6);
And that gives:
c/10-1.0 gives 0.000000e+00
c/10-2.0 gives 0.000000e+00
c/10-3.0 gives -1.110223e-16
c/10-4.0 gives -1.110223e-16
c/10-5.0 gives 0.000000e+00
c/10-6.0 gives 0.000000e+00
c/10-7.0 gives 0.000000e+00
c/10-8.0 gives 0.000000e+00
I think to get any further would require a detailed look at how the values are being represented in binary, and my enthusiasm for doing that is limited :-)
09:00
I agree sir. Thank you for spending a lot of time for this :-)
 
2 hours later…
11:11
Hi sir. If possible could you tell why do I get the error identifier "fo" is undefined sometimes even though I've written for?:
I read this thread over SO, according to which there must be some missing brace in my code. But I'm unable to find one. Moreover, if I delete for and retype it, it works properly till I run the program for two times.

« first day (252 days earlier)      last day (350 days later) »