How to set the limit for the limit : (1ā¤nā¤10^16)
for example
const int MAX_N = 1e16;
I am getting this error :
overflow in conversion from 'double' to 'int' changes value from '1.0e+16' to '2147483647'
Id you want to set a data type to its maxor min limit value, then you can use std::numeric_limits. Please read here about that.
And for having the maximum value for an int, you would write something like
int v = std::numeric_limits<int>::max();
Related
I have two times stored in int type in a struct and want to calculate the no. of hours elapsed in between two times. How do I correctly store the result of in a double variable. I seem to get the difference wrong. Also how do I store the result up to two places after the decimal point.
This is my code :
struct time
{
int hour=0,min=0;
char am_pm='a';
};
int main()
{
time t1,t2;
// GET THE TIME INPUT FROM THE USER HERE
//assuming always t2's hour and min are always numerically greater than t1's hour and min and always `am`
double hour_diff=0.00,min_diff=0.00;
double time_elapsed=0.00;
cout<<"The time elapsed between your entered times is : ";
hour_diff=t2.hour-t1.hour; counting hour difference
min_diff=(t2.min+t1.min)/60; //counting total minutes and converting them into hours
time_elapsed=hour_diff+min_diff;
cout<<time_elapsed;
if i give these input i get wrong result 7 when i should get 7.25 :
INPUT
t1.hour = 5
t1.min = 30
t1.am_pm = a;
t2.hour = 11
t2.min = 45
t2.am_pm = a;
time elapsed = 7 // this is wrong, I should be getting 7.25
The error is because this expression (t2.min+t1.min)/60 will return int.
That's because (t2.min+t1.min) is of type int and 60 is of type int. Hence \ will be an integer division operation.
To resolve it you can convert your (t2.min+t1.min) to the double with static_cast<double>(t2.min+t1.min). See more about static_cast.
Or you can simply define 60 as a double by writing 60.0.
Since you are performing integer operations '(t2.min + t1.min)/60', even though you are storing them in a variable of type double, become simplified to an integer type.
Either make 60 a double by changing it to '60.0' or encompass the whole result with a 'static_cast' before your operations.
I've got a problem with returned value by std::pow(). Basically, I have following line in the code:
#include <cmath>
int main()
{
double rate = 1.0033333333333334;
int m = 360;
unsigned int period = 1;
double res = std::pow(rate, -(m-period+1));
}
And res has a value of inf. However, when I paste std::pow(rate, -(m-period+1)) to Visual Studio watch while debugging it has a proper value of 0.30179586515268314. Does anyone know what's the source of this discrepancy?
See http://coliru.stacked-crooked.com/a/ec78c5172cf53e03
Your problem comes from the -(m-period+1) part of your call to pow. period is declared as
unsigned int period = 1;
so when
-(m-period+1)
gets evaluated you have
-(int - unsigned int + int)
== -(unsigned int)
so you get 360 as an unsigned int and when you negate it, it wraps around and becomes a very large number (4294966936 for a 32 bit int). That means you are doing
1.0033333333333334 ^ 4294966936
not
1.0033333333333334 ^ -360
You need to make period an int to get the correct results.
If you have a number that must not be negative, don't use an unsigned type. Nothing about unsigned stops negative numbers, it just turns them into a positive number. If you want to make sure a number isn't negative, use a signed type and an if statement.
I am trying to convert a large number going in to Megabytes. I don't want decimals
numeric function formatMB(required numeric num) output="false" {
return arguments.num \ 1024 \ 1024;
}
It then throws an error
How do I get around this?
You can't change the size of a Long, which is what CF uses for integers. So you'll need to BigInteger instead:
numeric function formatMB(required numeric num) {
var numberAsBigInteger = createObject("java", "java.math.BigInteger").init(javacast("string", num));
var mbAsBytes = 1024 ^ 2;
var mbAsBytesAsBigInteger = createObject("java", "java.math.BigInteger").init(javacast("string", mbAsBytes));
var numberInMb = numberAsBigInteger.divide(mbAsBytesAsBigInteger);
return numberInMb.longValue();
}
CLI.writeLn(formatMB(2147483648));
But as Leigh points out... for what you're doing, you're probably better off just doing this:
return floor(arguments.num / (1024 * 1024));
the size of a Long, which is what CF uses for integers
Small correction for those that may not read the comments. CF primarily uses 32 bit signed Integers, not Long (which has a much greater capacity). So as the error message indicates, the size limit here is the capacity of an Integer:
Integer.MAX_VALUE = 2147483647
Long.MAX_VALUE = 9223372036854775807
It is worth noting that although CF is relatively typeless, some Math and Date functions also have the same limitation. For example, although DateAdd technically supports milliseconds, if you try and use a very large number:
// getTime() - returns number of milliseconds since January 1, 1970
currentDate = dateAdd("l", now().getTime(), createDate(1970,1,1));
... it will fail with the exact same error because the "number" parameter must be an integer. So take note if the documentation mentions an "Integer" is expected. It does not just mean a "number" or "numeric" ...
This question is regarding the modulo operator %. We know in general a % b returns the remainder when a is divided by b and the remainder is greater than or equal to zero and strictly less than b. But does the above hold when a and b are of magnitude 10^9 ?
I seem to be getting a negative output for the following code for input:
74 41 28
However changing the final output statement does the work and the result becomes correct!
#include<iostream>
using namespace std;
#define m 1000000007
int main(){
int n,k,d;
cin>>n>>k>>d;
if(d>n)
cout<<0<<endl;
else
{
long long *dp1 = new long long[n+1], *dp2 = new long long[n+1];
//build dp1:
dp1[0] = 1;
dp1[1] = 1;
for(int r=2;r<=n;r++)
{
dp1[r] = (2 * dp1[r-1]) % m;
if(r>=k+1) dp1[r] -= dp1[r-k-1];
dp1[r] %= m;
}
//build dp2:
for(int r=0;r<d;r++) dp2[r] = 0;
dp2[d] = 1;
for(int r = d+1;r<=n;r++)
{
dp2[r] = ((2*dp2[r-1]) - dp2[r-d] + dp1[r-d]) % m;
if(r>=k+1) dp2[r] -= dp1[r-k-1];
dp2[r] %= m;
}
cout<<dp2[n]<<endl;
}
}
changing the final output statement to:
if(dp2[n]<0) cout<<dp2[n]+m<<endl;
else cout<<dp2[n]<<endl;
does the work, but why was it required?
By the way, the code is actually my solution to this question
This is a limit imposed by the range of int.
int can only hold values between ā2,147,483,648 to 2,147,483,647.
Consider using long long for your m, n, k, d & r variables. If possible use unsigned long long if your calculations should never have a negative value.
long long can hold values from ā9,223,372,036,854,775,808 to 9,223,372,036,854,775,807
while unsigned long long can hold values from 0 to 18,446,744,073,709,551,615. (2^64)
The range of positive values is approximately halved in signed types compared to unsigned types, due to the fact that the most significant bit is used for the sign; When you try to assign a positive value greater than the range imposed by the specified Data Type the most significant bit is raised and it gets interpreted as a negative value.
Well, no, modulo with positive operands does not produce negative results.
However .....
The int type is only guaranteed by the C standards to support values in the range -32767 to 32767, which means your macro m is not necessarily expanding to a literal of type int. It will fit in a long though (which is guaranteed to have a large enough range).
If that's happening (e.g. a compiler that has a 16-bit int type and a 32-bit long type) the results of your modulo operations will be computed as long, and may have values that exceed what an int can represent. Converting that value to an int (as will be required with statements like dp1[r] %= m since dp1 is a pointer to int) gives undefined behaviour.
Mathematically, there is nothing special about big numbers, but computers only have a limited width to write down numbers in, so when things get too big you get "overflow" errors. A common analogy is the counter of miles traveled on a car dashboard - eventually it will show as all 9s and roll round to 0. Because of the way negative numbers are handled, standard signed integers don't roll round to zero, but to a very large negative number.
You need to switch to larger variable types so that they overflow less quickly - "long int" or "long long int" instead of just "int", the range doubling with each extra bit of width. You can also use unsigned types for a further doubling, since no range is used for negatives.
I tried initializing an int64 variable in the following way :
let k:int64 = 4000000000;;
However I got the following error message :
Error: Integer literal exceeds the range of representable integers of type int
How do I intialise k to a value of 4 billion? Thanks.
You should use L specifier to indicate an int64 literal:
let k = 4000000000L;;
Alternatively, since the number exceeds the range of int32, you can convert it from float:
let k = Int64.of_float 4000000000.;;