2

Basically my code is about calculating equilateral triangle perimeter. Given values are these:

3
2.5 3 5.15

First number defines how many triangles there are and the numbers in second line are each triangle's side length.

Here's my code:

#include <iostream>
#include <fstream>
#include <cmath>
#include <iomanip>
#include <algorithm>
#include <cstdlib>+
using namespace std;

double Strik(double a);
int main()
{
    int n;
    cin>>n;
    double arr[n];
    for(int i=0;i<n;i++){
        cin>>arr[i];
    }
        for(int i=0;i<n;i++){
        cout<<fixed<<setprecision(2)<<arr[i]<<" "<<Strik(arr[i])<<endl;
    }
    return 0;
}
double Strik(double a){
double s  = ((a*a)*sqrt(3))/4;
 return s;
 }

Cout needs to be like this:

2.5 2.71
3 3.90
5.15 11.48

But I get this:

2.5 2.71
3.00 3.90
5.15 11.48

Please help

3 Answers3

3

You can´t do this inside one cout statement only.

You´ll need a control statement before, which proofs if Strik(arr[i]) is an integral value or not. With the C libraries which are included in the C++ standard libraries we can compare the return value of the floorf() function in the header of math.h, with the actual value of Strik(arr[i]), as condition of an if statement, like if(floorf(Strik(arr[i])) == Strik(arr[i])) to accomplish that task:

So the relative part of the program shall look like this:

for(int i=0;i<n;i++)
{
    if(floorf(Strik(arr[i])) == Strik(arr[i]))
    {
       cout << fixed << setprecision(0) << arr[i] << " " << Strik(arr[i]) << endl;
    }

    else
    {
       cout << fixed << setprecision(2) << arr[i] << " " << Strik(arr[i]) << endl;
    }
}
  • @KrisW In this case, Indeed, `3` can´t and **shouldn´t** be abbreviated. But that is not subject of the question. The OP wants to display a complete integer without floating-point precision by using `cout`. He said that the value is a straight `3`, not `3.00001`. – RobertS supports Monica Cellio Feb 01 '20 at 15:13
  • Your solution would display "3.00", not "3.00001". Try it. I'd have expected a general solution, rather than one that works for the exact input values that were used an example. – KrisW Feb 01 '20 at 20:16
  • @KrisW When I test it with `double v = 3.000000`, I´ll get the result of `3` not `3.00` with this technique. i don´t know why it is different by you. - *I'd have expected a general solution, rather than one that works for the exact input values that were used an example.* - The OP asks for a method to show an *even* integer value which is of type `double`, like for example: `3.000000000` in the output of `cout` as `3`. The question is **not** about to convert an `double` value of f.e. `3.00000000001` to `3` nor to print it out as such. – RobertS supports Monica Cellio Feb 02 '20 at 08:57
  • I said double v = **3.00001** , not 3.00000. The value being close to, but not exactly, an integer is important, because it shows the error you're making. The inexactness of FP arithmetic often results in "near integer" values that are actually integers. There are many pitfalls in presenting FP values to users, which is why, when calculations must be reported, we use multiple-precision arithmetic instead. Incidentally, the OP is also wrong in what they're asking for, but if "no '.00' on the numbers" is what they ask for, the answer should at least follow what they want. – KrisW Feb 02 '20 at 12:56
1

std::setprecision specifies the maximum number of digits to use and if you want to get N digits all the time you need to use std::fixed.

#include <iostream>
#include <iomanip>

int main()
{
    double a = 3.5;
    std::cout << std::fixed;
    std::cout << std::setprecision(4);
    std::cout << a << "\n";
    return 0;
}

And now the output is 3.5000.

Opposite from std::fixed is std::defaultfloat and in the first column you need std::defaultfloat but in the second column you need std::fixed so this is the way to go for you:

cout << defaultfloat << setprecision(2) << arr[i] << " ";
cout << fixed << Strik(arr[i]) << endl;

Check out live

UPDATE

If, as said in one of the comments, you want to output number 13.6, then you need to increase precision like this:

cout << defaultfloat << setprecision(3) << arr[i] << " ";
cout << fixed << setprecision(2) << Strik(arr[i]) << endl;
Ruben Helsloot
  • 12,582
  • 6
  • 26
  • 49
NutCracker
  • 11,485
  • 4
  • 44
  • 68
  • You haven't answered the OP's question. They are looking to display the output numbers at their shortest form, subject to a maximum number of two digits after the decimal point. – KrisW Feb 01 '20 at 14:28
  • @KrisW that's exactly what I explained in the second part of the answer, and that's exactly what the live demo does – NutCracker Feb 01 '20 at 14:39
  • But change arr[0] to 13.6 and see what happens... You really wanted to display "14" there?? – KrisW Feb 01 '20 at 14:44
  • @KrisW then OP just needs to increase the precision – NutCracker Feb 01 '20 at 15:00
  • Increasing the precision will result in additional digits after the decimal point. What they're looking to do cannot be done with iomanip. – KrisW Feb 01 '20 at 15:03
0

You cannot do what you want with the standard C++ manipulators.

Your options are:

  1. << std::fixed << std::precision(2) << sets the exact number of decimal places to 2
2.50 2.71
3.00 3.90
5.15 11.48
  1. << std::precision(2) << sets the number of significant digits to 2
2.5 2.7
3 3.9
5.1 11

You might think that std::setprecision(3) is the answer to your problem, but watch what happens when you try to print 115.7 :

116

Oops.

If this is really important to you, the only way to achieve it (without the enormous hassle of writing an iostream manipulator) is to do the conversion from double-to-string yourself and post-process the results..

Version 1: Trim all trailing zeros

#include <iostream>
#include <strstream>
#include <iomanip>
#include <string>


const std::string trim( double d )
{
   const int places=2;
   std::ostringstream out;
   out << std::setprecision(places) << std::fixed << d;
   std::string s = out.str(); // "3.19" or "5.00" or "212.70"
   s = s.substr( 0,  s.find_last_not_of( "0" )+1 );
   if ( s[s.size()-1]=='.') { s.erase(s.size()-1); }
   return s;
}

 ...

 cout<<trim(arr[i])<<" "<<trim(Strik(arr[i]))<<endl;

Version 2: Trim ".00" from integers, leave all others in place

const std::string trim( double d )
{
   const int places=2;
   std::ostringstream out;
   out << std::setprecision(places) << std::fixed << d;
   std::string s = out.str(); // "3.19" or "5.00" or "212.70"
   if ( s[s.size()-1]=='0' && s[s.size()-2]=='0') { s.erase(s.size()-3); }
   return s;
}
KrisW
  • 253
  • 1
  • 7