Why does the output always show 0 as LCM? - c++

https://github.com/mehedihasrifat
Please correct my mistake**
How can I solve this issue?
Did I do something wrong here?**
I have been trying to debug this code but ultimately I can't. Please help me, I'm totally new to this platform.
This picture shows the following code
/*
Written by Mehedi Hasan Rifat
Written on October 2, 2022
*/
#include <stdio.h>
int main()
{
int a, b, t, gcd, lcm;
printf("Enter two numbers: ");
scanf("%d %d", &a, &b);
if (a == 0)
gcd = b;
else if (b == 0)
gcd = a;
else
{
while (b != 0)
{
t = b;
b = a % b;
a = t;
}
gcd = a;
}
lcm = (a * b) / gcd;
printf("LCM: %d\n", lcm);
return 0;
}

As jasonharper says in the comment, when you finished the gcd calculation, b will be always zero.
One quick fix is to add
int original_a = a;
int original_b = b;
and calculate lcm using:
lcm = (original_a * original_b) / gcd;
Or just use the __gcd() function in the <algorithm> library.
#include <algorithm>
int main()
{
...
lcm = (a * b) / std::__gcd(a, b);
}

Related

Karatsuba Implementation C++

So I've decided to take a stab at implementing Karatsuba's algorithm in C++ (haven't used this language since my second coding class a life time ago so I'm very very rusty). Well anyhow, I believe that I've followed the pseudocode line by line but my algorithm still keeps popping up with the wrong answer.
x = 1234, y = 5678
Actual Answer: x*y ==> 7006652
Program output: x*y ==> 12272852
*Note: I'm running on a mac and using the following to create the executable to run c++ -std=c++11 -stdlib=libc++ karatsuba.cpp
Anywho, here's the code drafted up and feel free to make some callouts on what I'm doing wrong or how to improve upon c++.
Thanks!
Code:
#include <iostream>
#include <tuple>
#include <cmath>
#include <math.h>
using namespace std;
/** Method signatures **/
tuple<int, int> splitHalves(int x);
int karatsuba(int x, int y, int n);
int main()
{
int x = 5678;
int y = 1234;
int xy = karatsuba(x, y, 4);
cout << xy << endl;
return 0;
}
int karatsuba(int x, int y, int n)
{
if (n == 1)
{
return x * y;
}
else
{
int a, b, c, d;
tie(a, b) = splitHalves(x);
tie(c, d) = splitHalves(y);
int p = a + b;
int q = b + c;
int ac = karatsuba(a, c, round(n / 2));
int bd = karatsuba(b, d, round(n / 2));
int pq = karatsuba(p, q, round(n / 2));
int acbd = pq - bd - ac;
return pow(10, n) * ac + pow(10, round(n / 2)) * acbd + bd;
}
}
/**
* Method taken from https://stackoverflow.com/questions/32016815/split-integer-into-two-separate-integers#answer-32017073
*/
tuple<int, int> splitHalves(int x)
{
const unsigned int Base = 10;
unsigned int divisor = Base;
while (x / divisor > divisor)
divisor *= Base;
return make_tuple(round(x / divisor), x % divisor);
}
There are a lot of problems in your code...
First, you have a wrong coefficient here:
int q = b + c;
Has to be:
int q = c + d;
Next, the implementation of splitHalves doesn't do the work. Try that:
tuple<int, int> splitHalves(int x, int power)
{
int divisor = pow(10, power);
return make_tuple(x / divisor, x % divisor);
}
That would give you the "correct" answer for your input, but... that is not a Karatsuba method.
First, keep in mind that you don't need to "split in halves". Consider 12 * 3456. splitting the first number to halves mean a = 0, b = 12, while your implementation gives a = 1, b = 2.
Overall Karastuba works with arrays, not integers.

How do I solve this middle number problem?

Write a program where the user inputs 3 float numbers and the program checks which is medium size number. Example : a = 1.5, b = 7.8, and c = 3.0 and output should be c.
This is what I've tried and it worked for one case, but I'm still doing too much spaghetti code and I'm still learning how to write code efficiently.
My code:
#include <stdio.h>
int main(){
float a, b, c;
scanf("%f %f %f", &a, &b, &c);
if(a < b && c < a)
printf("%.1f", a);
else if(b < a && b > c)
printf("%.1f", b);
else if(c > a && c < b)
printf("%.1f", c);
else
{
printf("not good"); //I wrote this part to check if the code is good
}
return 0;
}
I'm still trying to get the hang of the if loops and I was just confused with this problem. Do you have any suggestions?
think of like, if a is medium , then b is medium, then c is medium. Check if that hepls!
#include <stdio.h>
int main(){
float a, b, c;
scanf("%f %f %f", &a, &b, &c);
if((a > b && a < c) || (a > c && a < b) )
printf("%.1f", a);
else if((b > a && b < c) || (b > c && b < a))
printf("%.1f", b);
else if((c > a && c < b) || (c > b && c < a))
printf("%.1f", c);
else
{
printf("not good"); //I wrote this part to check if the code is good
}
return 0;
}
If you can use C++:
#include <stdio.h>
#include <vector>
#include <algorithm>
using namespace std;
int main(){
float a, b, c;
scanf("%f %f %f", &a, &b, &c);
// Put them in a vector. Could use array, but vector more flexible
vector<float> vals = {a,b,c};
// Sort in numerical order
sort (vals.begin(),vals.end());
// Display the middle one
printf("%.1f", vals[1]);
return 0;
}

Trying to calculate GCD in C++

I think I am not calling the function or passing it correctly. Here are a couple of snippets that I am having issues with.
Using test data, 1/2 and 8/16 returns 1/2 instead of 1/1.
This is my code to calculate the GCD:
void Fractions::gcd(int n, int d)
{
int a,b,c;
a = n;
b = d;
while (a%b != 0)
{
c = a % b;
a = b;
b = c;
}
num = n/b;
denom = d/b;
}
This is the code that calculates will add numbers from input and calculate the GCD based from those numbers:
Fractions Fractions::operator+(Fractions& fraction2)
{
Fractions totalAddition;
totalAddition.num = (num * fraction2.denom + denom * fraction2.num);
totalAddition.denom = (denom * fraction2.denom);
totalAddition.gcd(num, denom); // i think issue is here
return totalAddition;
}
The only problem here is the name of the function.
A function called gcd should return the Greatest Common Divisor:
int gcd(int n, int d) {
int a, b, c;
a = n;
b = d;
while (a % b != 0) {
c = a % b;
a = b;
b = c;
}
return b;
}
It doesn't need to be a member function of Fraction to do this - it can be a standalone function, which is better, as it makes Fraction more encapsulated. But you can give it an overload which digests Fraction:
int gcd(const Fraction& frac){
return gcd(frac.numerator(), frac.denominator());
}
The name gcd is on the terse side but clear enough in context.
What your function is doing is it's simplifying a fraction, as a member function of a Fraction object, and overwriting that Fraction's member variables. So, it should be called simplify, and it doesn't need to take any input:
void Fractions::simplify() {
int a, b, c;
a = num;
b = denom;
while (a % b != 0) {
c = a % b;
a = b;
b = c;
}
num = n / b;
denom = d / b;
}
You might find you don't need a gcd function in which case simplify will be enough. But if you do need both functions, you can avoid some duplication of code here:
void Fractions::simplify() {
int g = gcd(*this);
num /= g;
denom /= g;
}
//Euclidean algorithm
//if b<a the gcd(a,b)=gcd(a-b,b)
int gcd(int a,int b)
{
while(a!=b)
{
if(a>b)
a=a-b;
else
b=b-a;
}
return a;
}
Output
15 12
3
//Optimal implementation of Euclidean Algorithm
int gcd(int a,int b)
{
if(b==0)
return a;
else
return gcd(b,a%b);
}
Output
15 12
3

Rounding integer division without logical operators

I want a function
int rounded_division(const int a, const int b) {
return round(1.0 * a/b);
}
So we have, for example,
rounded_division(3, 2) // = 2
rounded_division(2, 2) // = 1
rounded_division(1, 2) // = 1
rounded_division(0, 2) // = 0
rounded_division(-1, 2) // = -1
rounded_division(-2, 2) // = -1
rounded_division(-3, -2) // = 2
Or in code, where a and b are 32 bit signed integers:
int rounded_division(const int a, const int b) {
return ((a < 0) ^ (b < 0)) ? ((a - b / 2) / b) : ((a + b / 2) / b);
}
And here comes the tricky part: How to implement this guy efficiently (not using larger 64 bit values) and without a logical operators such as ?:, &&, ...? Is it possible at all?
The reason why I am wondering of avoiding logical operators, because the processor I have to implement this function for, has no conditional instructions (more about missing conditional instructions on ARM.).
a/b + a%b/(b/2 + b%2) works quite well - not failed in billion+ test cases. It meets all OP's goals: No overflow, no long long, no branching, works over entire range of int when a/b is defined.
No 32-bit dependency. If using C99 or later, no implementation behavior restrictions.
int rounded_division(int a, int b) {
int q = a / b;
int r = a % b;
return q + r/(b/2 + b%2);
}
This works with 2's complement, 1s' complement and sign-magnitude as all operations are math ones.
How about this:
int rounded_division(const int a, const int b) {
return (a + b/2 + b * ((a^b) >> 31))/b;
}
(a ^ b) >> 31 should evaluate to -1 if a and b have different signs and 0 otherwise, assuming int has 32 bits and the leftmost is the sign bit.
EDIT
As pointed out by #chux in his comments this method is wrong due to integer division. This new version evaluates the same as OP's example, but contains a bit more operations.
int rounded_division(const int a, const int b) {
return (a + b * (1 + 2 * ((a^b) >> 31)) / 2)/b;
}
This version still however does not take into account the overflow problem.
What about
...
return ((a + (a*b)/abs(a*b) * b / 2) / b);
}
Without overflow:
...
return ((a + ((a/abs(a))*(b/abs(b))) * b / 2) / b);
}
This is a rough approach that you may use. Using a mask to apply something if the operation a*b < 0.
Please note that I did not test this appropriately.
int function(int a, int b){
int tmp = float(a)/b + 0.5;
int mask = (a*b) >> 31; // shift sign bit to set rest of the bits
return tmp - (1 & mask);//minus one if a*b was < 0
}
The following rounded_division_test1() meets OP's requirement of no branching - if one counts sign(int a), nabs(int a), and cmp_le(int a, int b) as non-branching. See here for ideas of how to do sign() without compare operators. These helper functions could be rolled into rounded_division_test1() without explicit calls.
The code demonstrates the correct functionality and is useful for testing various answers. When a/b is defined, this answer does not overflow.
#include <limits.h>
#include <math.h>
#include <stdlib.h>
#include <stdio.h>
#include <string.h>
#include <errno.h>
int nabs(int a) {
return (a < 0) * a - (a >= 0) * a;
}
int sign(int a) {
return (a > 0) - (a < 0);
}
int cmp_le(int a, int b) {
return (a <= b);
}
int rounded_division_test1(int a, int b) {
int q = a / b;
int r = a % b;
int flag = cmp_le(nabs(r), (nabs(b) / 2 + nabs(b % 2)));
return q + flag * sign(b) * sign(r);
}
// Alternative that uses long long
int rounded_division_test1LL(int a, int b) {
int c = (a^b)>>31;
return (a + (c*2 + 1)*1LL*b/2)/b;
}
// Reference code
int rounded_division(int a, int b) {
return round(1.0*a/b);
}
int test(int a, int b) {
int q0 = rounded_division(a, b);
//int q1 = function(a,b);
int q1 = rounded_division_test1(a, b);
if (q0 != q1) {
printf("%d %d --> %d %d\n", a, b, q0, q1);
fflush(stdout);
}
return q0 != q1;
}
void tests(void) {
int err = 0;
int const a[] = { INT_MIN, INT_MIN + 1, INT_MIN + 1, -3, -2, -1, 0, 1, 2, 3,
INT_MAX - 1, INT_MAX };
for (unsigned i = 0; i < sizeof a / sizeof a[0]; i++) {
for (unsigned j = 0; j < sizeof a / sizeof a[0]; j++) {
if (a[j] == 0) continue;
if (a[i] == INT_MIN && a[j] == -1) continue;
err += test(a[i], a[j]);
}
}
printf("Err %d\n", err);
}
int main(void) {
tests();
return 0;
}
Let me give my contribution:
What about:
int rounded_division(const int a, const int b) {
return a/b + (2*(a%b))/b;
}
No branch, no logical operators, only mathematical operators. But it could fail if b is great than INT_MAX/2 or less than INT_MIN/2.
But if 64 bits are allowed to compute 32 bits rounds. It will not fail
int rounded_division(const int a, const int b) {
return a/b + (2LL*(a%b))/b;
}
Code that I came up with for use on ARM M0 (no floating point, slow divide).
It only uses one divide instruction and no conditionals, but will overflow if numerator + (denominator/2) > INT_MAX.
Cycle count on ARM M0 = 7 cycles + the divide (M0 has no divide instruction, so it is toolchain dependant).
int32_t Int32_SignOf(int32_t val)
{
return (+1 | (val >> 31)); // if v < 0 then -1, else +1
}
uint32_t Int32_Abs(int32_t val)
{
int32_t tmp = val ^ (val >> 31);
return (tmp - (val >> 31));
// the following code looks like it should be faster, using subexpression elimination
// except on arm a bitshift is free when performed with another operation,
// so it would actually end up being slower
// tmp = val >> 31;
// dst = val ^ (tmp);
// dst -= tmp;
// return dst;
}
int32_t Int32_DivRound(int32_t numerator, int32_t denominator)
{
// use the absolute (unsigned) demominator in the fudge value
// as the divide by 2 then becomes a bitshift
int32_t sign_num = Int32_SignOf(numerator);
uint32_t abs_denom = Int32_Abs(denominator);
return (numerator + sign_num * ((int32_t)(abs_denom / 2u))) / denominator;
}
since the function seems to be symmetric how about sign(a/b)*floor(abs(a/b)+0.5)

What parameters this formula takes when in "accumulate"?

This code is copied from another user question and I`m curious how accumulate works here.
I get the correct result from this code, but would like to know what parameters lcm takes when in "accumulate". The init as A and the sum of the range as b? Please help
#include <numeric>
int gcd(int a, int b)
{
for (;;)
{
if (a == 0) return b;
b %= a;
if (b == 0) return a;
a %= b;
}
}
int lcm(int a, int b)
{
int temp = gcd(a, b);
return temp ? (a / temp * b) : 0;
}
int main()
{
int arr[] = { 5, 7, 9, 12 };
int result = std::accumulate(arr, arr + 4, 1, lcm);
std::cout << result << '\n';
}
The first argument that lcm will take is the accumulated value so far (which starts at 1, the third argument of std::accumulate), and the second argument will be an element in arr. Next, whatever lcm returns is passed as the first argument and the next element in arr as the second.
See a reference for more details.
You could easily write a and b to the standard output inside lcm to see what's happening.