I need to get a random number in the range from a to b with n decimal places - c++

I need a function that returns me a random number with n decimal places
Example:
int aleatorio(int li, int ls)
{
return rand()%(ls+1-li)+li;
}
What i want is:
float new_random(int start, int final, int number_decimals)
{
return // What should I write here?
}
if I would call this function 5 times like this::
new_random(0, 5, 4);
The exit would be:
0.2344
3.4356
2.8435
4.2435
I do not want to use this, because I need numbers of 4 exact decimal places since I will not use them to print, but you will have others:
cout << setprecision(4) << 4.24359675967 << endl; //I do not want this

I need numbers of 4 exact decimal places
Then you cannot use finite precision binary floating point (i.e. float, double or long double) because those types cannot exactly represent all of the values with 4 decimal places.
A solution is to use arbitrary precision floating point, and another is to use fixed point. C++ standard doesn't provide arbitrary precision types nor fixed point types. Another approach is to give up the requirement of exactly representing those values and accept the almost exact values that are achievable with limited precision.

Try this for a Java solution. Multiply the start and finish by 1000, generating ints between the range and then divide the resultant number by 1000 as a double.
int start = 20;
int finish = 30;
int count = 10;
Random r = new Random();
r.ints(start * 1000, finish * 1000).filter(n -> n % 10 != 0)
.limit(count).mapToDouble(n -> n / 1000.)
.forEach(System.out::println);
prints something like this.
21.186
26.983
25.345
20.764
27.911
21.139
24.679
27.722
29.443
28.675
Or as a method supplying the starting number, ending number and precision.
for (int i = 0; i < 10; i++) {
System.out.println(newRandom(start,finish,4));
}
static Random r = new Random();
public static Double newRandom(int start, int finish, int precision) {
int f = (int)Math.pow(10,precision);
return r.ints(start * f, finish * f).filter(n -> n % 10 != 0)
.limit(1).mapToDouble(n -> n / (double)f).findFirst().getAsDouble();
}
Prints something like this.
28.4444
25.0259
29.5611
25.6445
25.4977
28.5124
28.9709
23.4835
27.9766
23.9438

You can generate an integer number N between start and final * 10^number_decimals and then return N / 10^number_decimals
Eg. start = 0, final = 5, number_decimals = 4 ==> N in [0 - 50000] ==> N/10000 in [0.0000 - 5.0000]
float new_random(int start, int final, int number_decimals) {
return aleatorio(start, final*pow10(number_decimals))/number_decimals;
}
You can define pow10 as:
int pow10(int p) {
if (p == 0) return 1;
else return 10 * pow10(p-1);
}

Related

What is the most efficient way to get the length of common prefix between two integers?

What is the most efficient way to get the length of common prefix and extract out the uncommon suffixes.
int a = 866559999;
int b = 866560000;
Basically I am looking to extract out 60000 and 59999 in the above example possibly in O(1) time i.e. without traversing the number and taking mod by 10. Probably this can be done using bitwise operator.
You can still vectorize the integer - to - string conversion to have speedup.
Here is auto-vectorized integer-to-string conversion with some benchmarking:
// https://github.com/tugrul512bit/VectorizedKernel/blob/main/VectorizedKernel.h
#include "VectorizedKernel.h"
#include <iostream>
#include <string>
int main()
{
constexpr int simd =16;
auto kernelVectorized = Vectorization::createKernel<simd>(
[&](auto & factory,
auto & idThread,
unsigned int * bufferIn,
char * bufferOut
)
{
const int currentSimdWidth = factory.width;
auto digitsReversed = factory.template generateArray<unsigned int,12>();
auto digitAsChar = factory.template generate<char>();
auto tmp = factory.template generate<unsigned int>();
auto tmp2 = factory.template generate<unsigned int>();
auto tmp3 = factory.template generate<unsigned int>();
auto value = factory.template generate<unsigned int>();
auto writeIndex = factory.template generate<int>();
for(int j=0;j<N;j+=simd)
{
// null termination
digitsReversed[0].broadcast(0);
writeIndex.readFrom(idThread);
value.readFrom(bufferIn+j,idThread);
// 11 digits!!??
for(int i=1;i<11;i++)
{
// fast-modulo to re-use the division
// value % 10 --> tmp (digit)
value.div((unsigned int)10,tmp3);
tmp3.mul((unsigned int)10,tmp2);
value.sub(tmp2,tmp);
// value /= 10
value.readFrom(tmp3);
// write digit character
tmp.add((unsigned int)'0',digitsReversed[i]);
}
writeIndex.mul(12,writeIndex);
for(int i=0;i<11;i++)
{
digitsReversed[11-i-1].template castAndCopyTo<char>(digitAsChar);
digitAsChar.writeTo(bufferOut+(j*12),writeIndex);
writeIndex.add((int)1,writeIndex);
}
}
},
/* defining kernel parameter types */
Vectorization::KernelArgs<unsigned int*,char*>{});
std::vector<unsigned int> testInput(N);
std::vector<std::string> testOutput(N);
std::vector<char> testOutputChar(N*12);
for(int i=0;i<N;i++)
{
testInput[i]=50000000+i;
}
size_t t;
for(int j=0;j<20;j++)
{
{
Vectorization::Bench bench(&t);
for(int i=0;i<N;i++)
{
testOutput[i]=std::to_string(testInput[i]);
}
}
std::cout<<t<<" nanoseconds (non-vectorized)"<<std::endl;
}
for(int i=0;i<20;i++)
{
{
Vectorization::Bench bench(&t);
kernelVectorized.run(simd,testInput.data(),testOutputChar.data());
}
std::cout<<t<<" nanoseconds (vectorized !!!)"<<std::endl;
}
for(int i=0;i<200;i++)
{
std::cout<<std::string(testOutputChar.data()+(i*12))<<" =?= "<<testOutput[i]<<std::endl;
}
return 0;
}
For FX8150, conversion for 1 million integers is 50 milliseconds with std::to_string and 32 milliseconds with vectorized version. On Cascadelake CPU, it is 24 milliseconds and 7.1 milliseconds respectively. These include writing zero-padded string to target string array.
If you are going to work with zero-padded format, then you need to skip the first n zeroes.
When string characters are not written to target, it has higher speedup but then to fully compute your algorithm, you still need to stringify the second parameter which will take another 7.1 milliseconds per 1 million inputs (making 14.2 milliseconds total) then do the comparison which would take similar time ~28 milliseconds total for Cascadelake CPU.
Same kernel with two variable converted at a time, from two input arrays:
https://godbolt.org/z/vdPhGK194
25384216 nanoseconds (non-vectorized)
25418696 nanoseconds (non-vectorized)
25396651 nanoseconds (non-vectorized)
9843377 nanoseconds (vectorized !!!)
8936126 nanoseconds (vectorized !!!)
8776456 nanoseconds (vectorized !!!)
8585255 nanoseconds (vectorized !!!)
8558483 nanoseconds (vectorized !!!)
We can test for
a == b => 10/10 common digits, else
a/10 == b/10 => 9/10 common digits, else
a/100 == b/100 => 8/10 common digit, else
a/1000 == b/1000 => 7/10 common digits, else
a/10000 == b/10000 => 6/10 common digits, else
a/100000 == b/100000 => 5/10 common digit, else
a/1000000 == b/1000000 => 4/10 common digits, else
a/10000000 == b/10000000 => 3/10 common digits, else
a/100000000 == b/100000000 => 2/10 common digit, else
a/1000000000 == b/1000000000 => 1/10 common digit, else 0/10 common digits.
Those divisions by a constant can be optimized with inverse multiplication constants instead, and be parallelized with SIMD instructions for multiplication, rightshift and comparison.
By extracting the prime factor 2 of the powers of 10, part of the division can be done with boolean ANDing, reducing the number of needed bits for the multiplication.
In the end it would be branchless and only take few cycles.
For extracting out the deviating suffixes one would multiply one of the two inputs of the topmost successful comparison (they are the same, if the comparison is successful) with the divisor and subtract it from both a and b. If none is successful one would just return a and b themselves.
A not so efficient an approach, but a baseline to compare. Does not use %. as requested by OP.
int count_common(unsigned a, unsigned b) {
// Find power of 10 for a, b
const unsigned pow10_max = 1000u*1000*1000;
unsigned apow10 = pow10_max;
while (a < apow10 && apow10 > 0) {
apow10 /= 10;
}
unsigned bpow10 = pow10_max;
while (b < bpow10 && bpow10 > 0) {
bpow10 /= 10;
}
int count = 0;
while (a > 0 && b > 0) {
unsigned aquot = a/apow10;
unsigned bquot = b/bpow10;
if (aquot != bquot) break;
count++;
a -= aquot*apow10;
apow10 /= 10;
b -= bquot*bpow10;
bpow10 /= 10;
}
return count;
}

c++ changing number digits places?

I have a 3 digit number, let's say n = 135. I need to change the digits in the number so that I get a different number. Putting first number in the middle for the result of 315. I figured first thing i have to do is extract separate digits and I went with this
int n = 135;
int a, b, c, x;
a = n / 100;
b = n % 100 / 10;
c = n % 10;
Now I have separate digit values but no idea how to put them all together into one variable to get x = 315.
EDIT:
Figured it out after writing. Don't know how to mark post as solved without choosing an answer. Solved it like this (if someone else encounters same problem):
x = b * 10 + a;
x = x * 10 + c;
cout << "Changed number: " << x << endl;
Multiplication is your friend.
x = b * 100 + a * 10 + c;
So, alright. The way I would do this, and please correct me if this doesn't work, would be to make it into a string, and then re-arrange stuff like that. To do that, we could use the string formatting library like this:
string number = to_string(135);
Then, you could do stuff like this:
char swap;
swap = number[0];
number[0] = number[1];
number[1] = swap;
That'll swap the first and second items, making it 315. The others follow logically. After you're done, just convert the string back to an int, like this:
int number = atoi(number.c_str());

How to store output of very large Fibonacci number?

I am making a program for nth Fibonacci number. I made the following program using recursion and memoization.
The main problem is that the value of n can go up to 10000 which means that the Fibonacci number of 10000 would be more than 2000 digit long.
With a little bit of googling, I found that i could use arrays and store every digit of the solution in an element of the array but I am still not able to figure out how to implement this approach with my program.
#include<iostream>
using namespace std;
long long int memo[101000];
long long int n;
long long int fib(long long int n)
{
if(n==1 || n==2)
return 1;
if(memo[n]!=0)
return memo[n];
return memo[n] = fib(n-1) + fib(n-2);
}
int main()
{
cin>>n;
long long int ans = fib(n);
cout<<ans;
}
How do I implement that approach or if there is another method that can be used to achieve such large values?
One thing that I think should be pointed out is there's other ways to implement fib that are much easier for something like C++ to compute
consider the following pseudo code
function fib (n) {
let a = 0, b = 1, _;
while (n > 0) {
_ = a;
a = b;
b = b + _;
n = n - 1;
}
return a;
}
This doesn't require memoisation and you don't have to be concerned about blowing up your stack with too many recursive calls. Recursion is a really powerful looping construct but it's one of those fubu things that's best left to langs like Lisp, Scheme, Kotlin, Lua (and a few others) that support it so elegantly.
That's not to say tail call elimination is impossible in C++, but unless you're doing something to optimise/compile for it explicitly, I'm doubtful that whatever compiler you're using would support it by default.
As for computing the exceptionally large numbers, you'll have to either get creative doing adding The Hard Way or rely upon an arbitrary precision arithmetic library like GMP. I'm sure there's other libs for this too.
Adding The Hard Way™
Remember how you used to add big numbers when you were a little tater tot, fresh off the aluminum foil?
5-year-old math
1259601512351095520986368
+ 50695640938240596831104
---------------------------
?
Well you gotta add each column, right to left. And when a column overflows into the double digits, remember to carry that 1 over to the next column.
... <-001
1259601512351095520986368
+ 50695640938240596831104
---------------------------
... <-472
The 10,000th fibonacci number is thousands of digits long, so there's no way that's going to fit in any integer C++ provides out of the box. So without relying upon a library, you could use a string or an array of single-digit numbers. To output the final number, you'll have to convert it to a string tho.
(woflram alpha: fibonacci 10000)
Doing it this way, you'll perform a couple million single-digit additions; it might take a while, but it should be a breeze for any modern computer to handle. Time to get to work !
Here's an example in of a Bignum module in JavaScript
const Bignum =
{ fromInt: (n = 0) =>
n < 10
? [ n ]
: [ n % 10, ...Bignum.fromInt (n / 10 >> 0) ]
, fromString: (s = "0") =>
Array.from (s, Number) .reverse ()
, toString: (b) =>
b .reverse () .join ("")
, add: (b1, b2) =>
{
const len = Math.max (b1.length, b2.length)
let answer = []
let carry = 0
for (let i = 0; i < len; i = i + 1) {
const x = b1[i] || 0
const y = b2[i] || 0
const sum = x + y + carry
answer.push (sum % 10)
carry = sum / 10 >> 0
}
if (carry > 0) answer.push (carry)
return answer
}
}
We can verify that the Wolfram Alpha answer above is correct
const { fromInt, toString, add } =
Bignum
const bigfib = (n = 0) =>
{
let a = fromInt (0)
let b = fromInt (1)
let _
while (n > 0) {
_ = a
a = b
b = add (b, _)
n = n - 1
}
return toString (a)
}
bigfib (10000)
// "336447 ... 366875"
Expand the program below to run it in your browser
const Bignum =
{ fromInt: (n = 0) =>
n < 10
? [ n ]
: [ n % 10, ...Bignum.fromInt (n / 10 >> 0) ]
, fromString: (s = "0") =>
Array.from (s) .reverse ()
, toString: (b) =>
b .reverse () .join ("")
, add: (b1, b2) =>
{
const len = Math.max (b1.length, b2.length)
let answer = []
let carry = 0
for (let i = 0; i < len; i = i + 1) {
const x = b1[i] || 0
const y = b2[i] || 0
const sum = x + y + carry
answer.push (sum % 10)
carry = sum / 10 >> 0
}
if (carry > 0) answer.push (carry)
return answer
}
}
const { fromInt, toString, add } =
Bignum
const bigfib = (n = 0) =>
{
let a = fromInt (0)
let b = fromInt (1)
let _
while (n > 0) {
_ = a
a = b
b = add (b, _)
n = n - 1
}
return toString (a)
}
console.log (bigfib (10000))
Try not to use recursion for a simple problem like fibonacci. And if you'll only use it once, don't use an array to store all results. An array of 2 elements containing the 2 previous fibonacci numbers will be enough. In each step, you then only have to sum up those 2 numbers. How can you save 2 consecutive fibonacci numbers? Well, you know that when you have 2 consecutive integers one is even and one is odd. So you can use that property to know where to get/place a fibonacci number: for fib(i), if i is even (i%2 is 0) place it in the first element of the array (index 0), else (i%2 is then 1) place it in the second element(index 1). Why can you just place it there? Well when you're calculating fib(i), the value that is on the place fib(i) should go is fib(i-2) (because (i-2)%2 is the same as i%2). But you won't need fib(i-2) any more: fib(i+1) only needs fib(i-1)(that's still in the array) and fib(i)(that just got inserted in the array).
So you could replace the recursion calls with a for loop like this:
int fibonacci(int n){
if( n <= 0){
return 0;
}
int previous[] = {0, 1}; // start with fib(0) and fib(1)
for(int i = 2; i <= n; ++i){
// modulo can be implemented with bit operations(much faster): i % 2 = i & 1
previous[i&1] += previous[(i-1)&1]; //shorter way to say: previous[i&1] = previous[i&1] + previous[(i-1)&1]
}
//Result is in previous[n&1]
return previous[n&1];
}
Recursion is actually discommanded while programming because of the time(function calls) and ressources(stack) it consumes. So each time you use recursion, try to replace it with a loop and a stack with simple pop/push operations if needed to save the "current position" (in c++ one can use a vector). In the case of the fibonacci, the stack isn't even needed but if you are iterating over a tree datastructure for example you'll need a stack (depends on the implementation though). As I was looking for my solution, I saw #naomik provided a solution with the while loop. That one is fine too, but I prefer the array with the modulo operation (a bit shorter).
Now concerning the problem of the size long long int has, it can be solved by using external libraries that implement operations for big numbers (like the GMP library or Boost.multiprecision). But you could also create your own version of a BigInteger-like class from Java and implement the basic operations like the one I have. I've only implemented the addition in my example (try to implement the others they are quite similar).
The main idea is simple, a BigInt represents a big decimal number by cutting its little endian representation into pieces (I'll explain why little endian at the end). The length of those pieces depends on the base you choose. If you want to work with decimal representations, it will only work if your base is a power of 10: if you choose 10 as base each piece will represent one digit, if you choose 100 (= 10^2) as base each piece will represent two consecutive digits starting from the end(see little endian), if you choose 1000 as base (10^3) each piece will represent three consecutive digits, ... and so on. Let's say that you have base 100, 12765 will then be [65, 27, 1], 1789 will be [89, 17], 505 will be [5, 5] (= [05,5]), ... with base 1000: 12765 would be [765, 12], 1789 would be [789, 1], 505 would be [505]. It's not the most efficient, but it is the most intuitive (I think ...)
The addition is then a bit like the addition on paper we learned at school:
begin with the lowest piece of the BigInt
add it with the corresponding piece of the other one
the lowest piece of that sum(= the sum modulus the base) becomes the corresponding piece of the final result
the "bigger" pieces of that sum will be added ("carried") to the sum of the following pieces
go to step 2 with next piece
if no piece left, add the carry and the remaining bigger pieces of the other BigInt (if it has pieces left)
For example:
9542 + 1097855 = [42, 95] + [55, 78, 09, 1]
lowest piece = 42 and 55 --> 42 + 55 = 97 = [97]
---> lowest piece of result = 97 (no carry, carry = 0)
2nd piece = 95 and 78 --> (95+78) + 0 = 173 = [73, 1]
---> 2nd piece of final result = 73
---> remaining: [1] = 1 = carry (will be added to sum of following pieces)
no piece left in first `BigInt`!
--> add carry ( [1] ) and remaining pieces from second `BigInt`( [9, 1] ) to final result
--> first additional piece: 9 + 1 = 10 = [10] (no carry)
--> second additional piece: 1 + 0 = 1 = [1] (no carry)
==> 9542 + 1 097 855 = [42, 95] + [55, 78, 09, 1] = [97, 73, 10, 1] = 1 107 397
Here is a demo where I used the class above to calculate the fibonacci of 10000 (result is too big to copy here)
Good luck!
PS: Why little endian? For the ease of the implementation: it allows to use push_back when adding digits and iteration while implementing the operations will start from the first piece instead of the last piece in the array.

Why does trunc(1) output as 0?

Can someone explain me why in c++ happens such a thing:
double tmp;
... // I do some operations with tmp
// after which it has to be equal to one
cout << tmp; // prints 1
cout << trunc(tmp); // prints 0
cout << trunc(tmp*10); // prints 9
I am using this for separation part right of decimal part from the number for example if i have: 5.010 ... i want to have 0.010 .. so I am using:
double remainder = tmp - trunc(tmp);
I am posting the whole code....the suggestion with floor does not worked
short getPrecision(double num, short maxPrecision) {
// Retrieve only part right of decimal point
double tmp = fabs(num - trunc(num));
double remainder = tmp;
// Count number of decimal places
int c = 0;
while (remainder > 0 && c < maxPrecision) {
tmp *= 10;
remainder = tmp - trunc(tmp);
c++;
}
return c;
}
When I run this function for example with 5.1 the remanider is 0 instead of 1
After some calculations it has to be one? Well, it could as well be 0.99999999999999999. Floating point operations are not precise, you should always take that into account.
Please see picture at http://en.cppreference.com/w/cpp/numeric/math/trunc. The chart there explains the inconsistency with truncing 1. Probably the same applies to 10 as well
This should help you achieving what you need:
double remainder = tmp - floor(tmp);

Finding a Specific Digit of a Number

I'm trying to find the nth digit of an integer of an arbitrary length. I was going to convert the integer to a string and use the character at index n...
char Digit = itoa(Number).at(n);
...But then I realized the itoa function isn't standard. Is there any other way to do this?
(number/intPower(10, n))%10
just define the function intPower.
You can also use the % operator and / for integer division in a loop. (Given integer n >= 0, n % 10 gives the units digit, and n / 10 chops off the units digit.)
number = 123456789
n = 5
tmp1 = (int)(number / 10^n); // tmp1 = 12345
tmp2 = ((int)(tmp1/10))*10; // tmp2 = 12340
digit = tmp1 - tmp2; // digit = 5
You can use ostringstream to convert to a text string, but
a function along the lines of:
char nthDigit(unsigned v, int n)
{
while ( n > 0 ) {
v /= 10;
-- n;
}
return "0123456789"[v % 10];
}
should do the trick with a lot less complications. (For
starters, it handles the case where n is greater than the number
of digits correctly.)
--
James Kanze
Itoa is in stdlib.h.
You can also use an alternative itoa:
Alternative to itoa() for converting integer to string C++?
or
ANSI C, integer to string without variadic functions
It is also possible to avoid conversion to string by means of the function log10, int cmath, which returns the 10th-base logarithm of a number (roughly its length if it were a string):
unsigned int getIntLength(int x)
{
if ( x == 0 )
return 1;
else return std::log10( std::abs( x ) ) +1;
}
char getCharFromInt(int n, int x)
{
char toret = 0;
x = std::abs( x );
n = getIntLength( x ) - n -1;
for(; n >= 0; --n) {
toret = x % 10;
x /= 10;
}
return '0' + toret;
}
I have tested it, and works perfectly well (negative numbers are a special case). Also, it must be taken into account that, in order to find tthe nth element, you have to "walk" backwards in the loop, subtracting from the total int length.
Hope this helps.
A direct answer is:
char Digit = 48 + ((int)(Number/pow(10,N)) % 10 );
You should include the <math> library
const char digit = '0' + number.at(n);
Assuming number.at(n) returns a decimal digit in the range 0...9, that is.
A more general approach:
template<int base>
int nth_digit(int value, int digit)
{
return (value / (int)pow((double)base, digit)) % base;
}
Just lets you do the same thing for different base numbers (e.g. 16, 32, 64, etc.).
An alternative to itoa is the std::to_string method. So, you could simply do:
char digit = to_string(number)[index]