Length calculator feet and inches - c#

In my if statement (LengthCalculatorOption == 1), I want to convert, for example, 187.96cm to feet and inches, such as 6feet 2ins. How do I do that? In my current code, it shows 6.17feet and always 0ins. I have no idea why.
static void Main(string[] args) {
double Centimetres = 0.0, Feet = 0.0, Inches = 0.0;
string AnotherConversion = null;
string LengthCalculatorMenu;
int LengthCalculatorOption;
do {
LengthCalculatorMenu = ("Enter 1) Convert centimetres to feet and inches:"
+ "\nEnter 2) Convert feet and inches to centimetres:");
Console.Write(LengthCalculatorMenu);
LengthCalculatorOption = int.Parse(Console.ReadLine());
if (LengthCalculatorOption == 1) {
Console.WriteLine("Please Enter the Centimetres(cm) that you wish to convert to feet and inches");
Centimetres = double.Parse(Console.ReadLine());
Feet = (Centimetres / 2.54) / 12;
Inches = (Centimetres / 2.54) - (Feet * 12);
Centimetres = ((Feet * 12) + Inches) * 2.54;
Console.WriteLine("\nThe equivalent in feet and inches is {0:C} ft {1:G} ins", Feet, Inches);
Console.Write("\nWould you like to make an another conversion? \n\n(Enter Y to make an another conversion/Enter any other key to exit):");
AnotherConversion = Console.ReadLine();
} else if (LengthCalculatorOption == 2) {
Console.WriteLine("Please Enter the Feet");
Feet = double.Parse(Console.ReadLine());
Console.WriteLine("Please Enter the Inches");
Inches = double.Parse(Console.ReadLine());
Centimetres = ((Feet * 12) + Inches) * 2.54;
Console.WriteLine("\nThe equivalent in centimetres is {0:G}cm", Centimetres);
Console.Write("\nWould you like to make an another conversion? \n\n(Enter Y to make an another conversion/Enter any other key to exit):");
AnotherConversion = Console.ReadLine();
} else {
Console.WriteLine("\n\a\t Invalid Option!Option Must be 1 or 2");
}
} while (AnotherConversion == "y" || AnotherConversion == "Y");

Try this:
Feet = (Centimetres / 2.54) / 12;
int iFeet = (int)Feet;
inches = (Feet - (double)iFeet) * 12;
To elaborate a bit:
You are defining feet as a double, which means that it will be a decimal value. So since you're dividing by 12, it can become a decimal representation.
What my code does is it converts Feet to integer (which will round it to 6 in this situation). We then subtract the double version of Feet (6.17 in this situation) which equals .17 (The remainder). We multiply that by 12 to convert from .17 feet to inches
Edit
To expand based on Scott's comment, this would be a different way to go
int totalInches = (Centimetres / 2.54); // This will take a floor function of Centimetres/2.54
int Feet = (totalInches - totalInches % 12) / 12; // This will make it divisible by 12
int inches = totalInches % 12; // This will give you the remainder after you divide by 12

To calculate a value in centimeters into feet and inches, you'd likely want to do this:
double centimeters = 187.96;
double inches = centimeters/2.54;
double feet = Math.Floor(inches / 12);
inches -= (feet*12);
Generally-speaking, one should convert down to the most basic level, then calculate your way up. This way, you only do the work of converting one time, instead of having to repeat the conversion calculation. In this insntance, I do the simple conversion of centimeters to inches, and then after that, count the number of feet in inches, then subtract that much from the final inches value.
So, if I had, say, 38 inches, I would have Math.Floor(38 / 12) feet, or 3. Then inches would be set to 38 - (3*12), which is 2, giving a final result of 3 feet, 2 inches.

Keeping it as double, use:
double inp = 12.75; // e.g.
double feet = Math.Floor(inp);
double inches = (inp - feet) * 12.0;

Try this:
double F = Math.Floor(Centimetres * 0.0328084);
Feet = Centimetres * 0.0328084;
Inches = (Feet - F) * 12;
1 ft = 0.30480m

Some general-purpose methods:
public static class Converter
{
public static (int Feet, double Inches) CentimetresToFeetInches(double centimetres)
{
var feet = centimetres / 2.54 / 12;
var iFeet = (int)feet;
var inches = (feet - iFeet) * 12;
return (iFeet, inches);
}
public static string CentimetresToFeetInchesString(double centimetres, string footSymbol = " foot", string inchesSymbol = " inches")
{
(var feet, var inches) = CentimetresToFeetInches(centimetres);
return $"{feet:N0}{footSymbol}, {inches:N0}{inchesSymbol}";
}
}
Usage:
(var feet, var inches) = Converter.CentimetresToFeetInches(178);
//feet == 5
//inches == 10.078740157480315
var feetInchesString = Converter.CentimetresToFeetInchesString(178);
//5 foot, 10 inches

Related

Math.round method turns thousands into hundreds

I'm trying to create a map-related calculator and I'm having a problem with the Math.Round method. Basically, I want the program to take the real-life length and the length on a map to calculate the scale of said map. After it calculates the scale it should round it from a double to an int.
So for example the real-life length is 3000000 cm and the on map length equals 8,5 cm now after dividing these we get 352 941,176 that's our scalenoteven in this context. Now after rounding it, the scale should be 1:352 941 but instead the program gives me a scale of 1:352.
double Scalenoteven;
int Scaleeven;
//RealLengthincm and Maplength are taken from the user
Scalenoteven = RealLengthincm / MapLength;
Scaleeven = (int)Math.Round(Scalenoteven, 1, MidpointRounding.ToEven);
So with the added culture info and RealLengthincm = RealLength * 100; this should be working.
using System.Globalization;
double RealLength;
string RealLengthString;
double MapLength;
string MapLengthString;
double RealLengthincm;
double Scalenoteven;
int Scaleeven;
Console.WriteLine("Firstly will the real length be in meters or kilometers?");
string Answer;
Answer = Console.ReadLine();
if (Answer == "meters")
{
Console.WriteLine("Alright!");
Console.WriteLine("So what's the real length?");
var culture = new CultureInfo("de-DE");
RealLengthString = Console.ReadLine(); // assuming 30000
RealLength = double.Parse(RealLengthString, culture);
RealLengthincm = RealLength * 100;
Console.WriteLine("now what's the length on the map in cm");
MapLengthString = Console.ReadLine(); // assuming 8,5
MapLength = double.Parse(MapLengthString, culture);
//RealLengthincm and Maplength are taken from the user
Scalenoteven = RealLengthincm / MapLength;
Scaleeven = (int)Math.Round(Scalenoteven, 0, MidpointRounding.ToZero);
Console.WriteLine("The Scale is 1:" + Scaleeven); // outputs 1:352941
}

Turning 2 textboxes into 1 variable for height and weight conversion in C#

I am creating a program that requires height and weight. The height has to be calculated as feet and inches, same with weight has to be stone and pounds. This requires 2 textboxes.
My question is how can i get the text boxes to turn into 1 variable?
use this function in Textbox Change or ButtonClick :
public long CalculateUnit(int flag , int number) //flag=Textbox Type
{
if(flag==1)
{
int totalInches = (number / 2.54); // This will take a floor function of Centimetres/2.54
int Feet = (totalInches - totalInches % 12) / 12; // This will make it divisible by 12
int inches = totalInches % 12; // This will give you the remainder after you divide by 12
result=inches; //or Feet
}
if(flag==2)
{
int Stone =number;
int Pounds = (Stone*14) ;
int Kilograms = (Pounds/2.2);
result=Kilograms; // or Pounds
}
return result;
}
}

C# value is always 0 console application

I have no idea why my BMI value is always = to 0. I am programming noob what am i missing? other than that is my if statement alright? what am i missing?
static void Main(string[] args) {
double WeightKg = 0.0, HeightCm = 0.0, Weightlbs = 0.0, WeightOz = 0.0, BMI = 0.0, Feet = 0.0, Inches = 0.0;
int BMIOption;
string AnotherConversion;
string BMIMenu = ("Which Measurement You Want to use to enter the weight and height?"
+ "\n1)Enter 1 for Metric"
+ "\n2)Enter 2 for British Imperial:");
Console.Write(BMIMenu);
BMIOption = int.Parse(Console.ReadLine());
if (BMIOption == 1) {
Console.Write("\nPlease Enter your Weight in Kilogram (kg):");
WeightKg = int.Parse(Console.ReadLine());
Console.Write("\nPlease Enter your Height in in centimetres (cm):");
HeightCm = int.Parse(Console.ReadLine());
BMI = WeightKg / (HeightCm * HeightCm);
if (BMI >= 35) {
Console.WriteLine("\nYour BMI is {0:C},Severe Obesity", BMI);
} else if (BMI >= 30) {
Console.WriteLine("\nYour BMI is {0:C},Obese", BMI);
} else if (BMI >= 25) {
Console.WriteLine("\nYour BMI is {0:C},OverWeight", BMI);
} else if (BMI >= 18.5) {
Console.WriteLine("\nYour BMI is {0:C},Healthy BodyWeight", BMI);
} else if (BMI <= 18.5) {
Console.WriteLine("\nYour BMI is {0:C},UnderWeight", BMI);
}//End if
Console.Write("\nWould you like to make an another conversion? \n\n(Enter Y to make an another conversion/Enter any other key to exit):");
Console.ReadKey();
BMI is calculated with meters, not centimeters. So you need to convert the HeightCm to HeightM. If you don't do this, you get really small number, that is then printed as 0.
double HeightM = HeightCm / 100.0;
BMI = WeightKg / (HeightM * HeightM);
Also, when parsing, use double.Parse instead of int.Parse. The way it is right now, you will only parse the number without the decimal part.
In this line:
BMI = WeightKg / (HeightCm * HeightCm);
The result ends up being very small (less than 1). Take an example where WeightKg is 55 and HeightCm is 165. The result is around 0.002.
When you display it as {0:C}, it's being displayed as zero. Use {0:G} to see the actual value.
even so your formula is wrong, as Martin says u must replace the int.Parse with double AND
BMI = WeightKg / ((HeightCm/100) * (HeightCm/100));
use this for calculation it is HEIGHT IN METERS :)

Split double into two int, one int before decimal point and one after

I need to split an double value, into two int value, one before the decimal point and one after. The int after the decimal point should have two digits.
Example:
10.50 = 10 and 50
10.45 = 10 and 45
10.5 = 10 and 50
This is how you could do it:
string s = inputValue.ToString("0.00", CultureInfo.InvariantCulture);
string[] parts = s.Split('.');
int i1 = int.Parse(parts[0]);
int i2 = int.Parse(parts[1]);
Manipulating strings can be slow. Try using the following:
double number;
long intPart = (long) number;
double fractionalPart = number - intPart;
What programming language you want to use to do this? Most of the language should have a Modulo operator. C++ example:
double num = 10.5;
int remainder = num % 1
"10.50".Split('.').Select(int.Parse);
/// <summary>
/// Get the integral and floating point portions of a Double
/// as separate integer values, where the floating point value is
/// raised to the specified power of ten, given by 'places'.
/// </summary>
public static void Split(Double value, Int32 places, out Int32 left, out Int32 right)
{
left = (Int32)Math.Truncate(value);
right = (Int32)((value - left) * Math.Pow(10, places));
}
public static void Split(Double value, out Int32 left, out Int32 right)
{
Split(value, 1, out left, out right);
}
Usage:
Int32 left, right;
Split(10.50, out left, out right);
// left == 10
// right == 5
Split(10.50, 2, out left, out right);
// left == 10
// right == 50
Split(10.50, 5, out left, out right);
// left == 10
// right == 50000
how about?
var n = 1004.522
var a = Math.Floor(n);
var b = n - a;
Another variation that doesn't involve string manipulation:
static void Main(string[] args)
{
decimal number = 10123.51m;
int whole = (int)number;
decimal precision = (number - whole) * 100;
Console.WriteLine(number);
Console.WriteLine(whole);
Console.WriteLine("{0} and {1}",whole,(int) precision);
Console.Read();
}
Make sure they're decimals or you get the usual strange float/double behaviour.
you can split with string and then convert into int ...
string s = input.ToString();
string[] parts = s.Split('.');
This function will take time in decimal and converts back into base 60 .
public string Time_In_Absolute(double time)
{
time = Math.Round(time, 2);
string[] timeparts = time.ToString().Split('.');
timeparts[1] = "." + timeparts[1];
double Minutes = double.Parse(timeparts[1]);
Minutes = Math.Round(Minutes, 2);
Minutes = Minutes * (double)60;
return string.Format("{0:00}:{1:00}",timeparts[0],Minutes);
//return Hours.ToString() + ":" + Math.Round(Minutes,0).ToString();
}
Try:
string s = "10.5";
string[] s1 = s.Split(new char[] { "." });
string first = s1[0];
string second = s1[1];
You can do it without going through strings. Example:
foreach (double x in new double[]{10.45, 10.50, 10.999, -10.323, -10.326, 10}){
int i = (int)Math.Truncate(x);
int f = (int)Math.Round(100*Math.Abs(x-i));
if (f==100){ f=0; i+=(x<0)?-1:1; }
Console.WriteLine("("+i+", "+f+")");
}
Output:
(10, 45)
(10, 50)
(11, 0)
(-10, 32)
(-10, 33)
(10, 0)
Won't work for a number like -0.123, though. Then again, I'm not sure how it would fit your representation.
I actually just had to answer this in the real world and while #David Samuel's answer did part of it here is the resulting code I used. As said before Strings are way too much overhead. I had to do this calculation across pixel values in a video and was still able to maintain 30fps on a moderate computer.
double number = 4140 / 640; //result is 6.46875 for example
int intPart = (int)number; //just convert to int, loose the dec.
int fractionalPart = (int)((position - intPart) * 1000); //rounding was not needed.
//this procedure will create two variables used to extract [iii*].[iii]* from iii*.iii*
This was used to solve x,y from pixel count in 640 X 480 video feed.
Console.Write("Enter the amount of money: ");
double value = double.Parse(Console.ReadLine());
int wholeDigits = (int) value;
double fractionalDigits = (value - wholeDigits) * 100;
fractionalDigits = (int) fractionalDigits;
Console.WriteLine(
"The number of the shekels is {0}, and the number of the agurot is {1}",
wholeDigits, fractionalDigits);
Using Linq. Just clarification of #Denis answer.
var parts = "10.50".Split('.').Select(int.Parse);
int i1 = parts.ElementAt(0);
int i2 = parts.ElementAt(1);

Formatting double to latitude/longitude human readable format

If the formula for converting latitude or longitude to double is
((Degree) + (Minute) / 60 + (Second) / 3600) * ((South || West) ? -1 : 1)
then what's the formula for parsing degrees, minutes, seconds from a double?
It'd make sense to have two separate methods for parsing latitude and longitude, but I'm not sure how to parse the degrees, minutes, seconds from the double.
ParseLatitude(double value)
{
//value is South if negative, else is North.
}
ParseLongitude(double value)
{
//value is West if negative, else is East.
}
Example coordinates:
latitude: 43.81234123
longitude: -119.8374747
The final code to convert back and forth, thanks again to Peter and James for the answer. I had to convert value to Decimal because this is being used in Silverlight and Math.Truncate(double) is not available):
public class Coordinate
{
public double Degrees { get; set; }
public double Minutes { get; set; }
public double Seconds { get; set; }
public CoordinatesPosition Position { get; set; }
public Coordinate() { }
public Coordinate(double value, CoordinatesPosition position)
{
//sanity
if (value < 0 && position == CoordinatesPosition.N)
position = CoordinatesPosition.S;
//sanity
if (value < 0 && position == CoordinatesPosition.E)
position = CoordinatesPosition.W;
//sanity
if (value > 0 && position == CoordinatesPosition.S)
position = CoordinatesPosition.N;
//sanity
if (value > 0 && position == CoordinatesPosition.W)
position = CoordinatesPosition.E;
var decimalValue = Convert.ToDecimal(value);
decimalValue = Math.Abs(decimalValue);
var degrees = Decimal.Truncate(decimalValue);
decimalValue = (decimalValue - degrees) * 60;
var minutes = Decimal.Truncate(decimalValue);
var seconds = (decimalValue - minutes) * 60;
Degrees = Convert.ToDouble(degrees);
Minutes = Convert.ToDouble(minutes);
Seconds = Convert.ToDouble(seconds);
Position = position;
}
public Coordinate(double degrees, double minutes, double seconds, CoordinatesPosition position)
{
Degrees = degrees;
Minutes = minutes;
Seconds = seconds;
Position = position;
}
public double ToDouble()
{
var result = (Degrees) + (Minutes) / 60 + (Seconds) / 3600;
return Position == CoordinatesPosition.W || Position == CoordinatesPosition.S ? -result : result;
}
public override string ToString()
{
return Degrees + "º " + Minutes + "' " + Seconds + "'' " + Position;
}
}
public enum CoordinatesPosition
{
N, E, S, W
}
Unit Test (nUnit)
[TestFixture]
public class CoordinateTests
{
[Test]
public void ShouldConvertDoubleToCoordinateAndBackToDouble()
{
const double baseLatitude = 43.81234123;
const double baseLongitude = -119.8374747;
var latCoordN = new Coordinate(baseLatitude, CoordinatesPosition.N);
var latCoordS = new Coordinate(baseLatitude, CoordinatesPosition.S);
var lonCoordE = new Coordinate(baseLongitude, CoordinatesPosition.E);
var lonCoordW = new Coordinate(baseLongitude, CoordinatesPosition.W);
var convertedLatitudeS = latCoordS.ToDouble();
var convertedLatitudeN = latCoordN.ToDouble();
var convertedLongitudeW = lonCoordW.ToDouble();
var convertedLongitudeE = lonCoordE.ToDouble();
Assert.AreEqual(convertedLatitudeS, convertedLatitudeN);
Assert.AreEqual(baseLatitude, convertedLatitudeN);
Assert.AreEqual(convertedLongitudeE, convertedLongitudeW);
Assert.AreEqual(baseLongitude, convertedLongitudeE);
}
}
ParseLatitude(double Value)
{
var direction = Value < 0 ? Direction.South : Direction.North;
Value = Math.Abs(Value);
var degrees = Math.Truncate(Value);
Value = (Value - degrees) * 60; //not Value = (Value - degrees) / 60;
var minutes = Math.Truncate(Value);
var seconds = (Value - minutes) * 60; //not Value = (Value - degrees) / 60;
//...
}
ParseLongitude(double Value)
{
var direction = Value < 0 ? Direction.West : Direction.East;
Value = Math.Abs(Value);
var degrees = Math.Truncate(Value);
Value = (Value - degrees) * 60; //not Value = (Value - degrees) / 60;
var minutes = Math.Truncate(Value);
var seconds = (Value - minutes) * 60; //not Value = (Value - degrees) / 60;
//...
}
EDIT
I came back to this because of a recent upvote. Here's a DRY-er version, with the Value parameter renamed to reflect the most common coding convention, in which parameters start with lower-case letters:
ParseLatitude(double value)
{
var direction = value < 0 ? Direction.South : Direction.North;
return ParseLatituteOrLongitude(value, direction);
}
ParseLongitude(double value)
{
var direction = value < 0 ? Direction.West : Direction.East;
return ParseLatituteOrLongitude(value, direction);
}
//This must be a private method because it requires the caller to ensure
//that the direction parameter is correct.
ParseLatitudeOrLongitude(double value, Direction direction)
{
value = Math.Abs(value);
var degrees = Math.Truncate(value);
value = (value - degrees) * 60; //not Value = (Value - degrees) / 60;
var minutes = Math.Truncate(value);
var seconds = (value - minutes) * 60; //not Value = (Value - degrees) / 60;
//...
}
#include <math.h>
void ParseLatitude(double Value, bool &north, double &deg, double &min, double &sec)
{
if ( Value < 0 )
{
ParseLatitude( -Value, north, deg, min, sec );
north = false;
}
else
{
north = true;
deg = floor(Value);
Value = 60*(Value - deg);
min = floor(Value);
Value = 60*(Value - min);
sec = Value;
}
}
// ParseLongitude is similar
I've written a class in C# which does a lot of this. Perhaps it is useful, otherwise you can check out the implementation:
http://code.google.com/p/exif-utils/source/browse/trunk/ExifUtils/ExifUtils/GpsCoordinate.cs
In addition to parsing out the degree, minutes, seconds (which is just radix 60 arithmetic), you may also want to deal with sign of the doubles being converted to "North/South" for latitude and "East/West" for longitude.
It's pretty standard to identify positive degrees latitude with the Northern Hemisphere and negative degrees latitude with the Southern Hemisphere. It's also common here in the Western Hemisphere to take positive degrees longitude to mean degrees West of the Greenwich Meridian and conversely negative degrees longitude to mean degrees East of that Meridian. However the preferred convention for this is the opposite, to take degrees East of the Greenwich Meridian as negative. You may want to consult with your client/analyze the application design to determine which choice applies to this conversion.
Note also that the discontinuity of longitude at ±180 is a cause for care in converting coordinates that may result from calculations. If the conversion is not intended to handle wrap-around at the 180° meridian, then it's likely an exception should be thrown for such inputs. Of course the design decision should be documented either way.
Certainly latitudes outside the ±90° range are errors on input.
Added: Given the above differences in parsing latitude and longitude, issues that would best be handled in the distinct ParseLatitude & ParseLongitude routines, we could use a common utility to do the conversion from double to degrees/minutes/seconds.
I'm not sure what the target language should be here, so I wrote something in plain vanilla C:
#include <math.h>
void double2DegMinSec(double angle, int *Sign, int *Deg, int *Min, double *Sec)
{ /* extract radix 60 Degrees/Minutes/Seconds from "angle" */
Sign = 1;
if (angle < 0.0) /* reduce to case of nonnegative angle */
{
Sign = -Sign;
angle = -angle;
}
*Deg = floor(angle);
angle -= *Deg;
angle *= 60.0;
*Min = floor(angle);
angle -= *Min;
angle *= 60.0;
*Sec = angle;
return;
}
Likely ParseLatitude and ParseLongitude should manage the conversion of angle's sign to the appropriate geographic designation, but I've included an argument Sign that will allow that sign checking to be done after conversion (though it would be fine if the conversion were only ever called with nonnegative angles).
I made the function double2DegMinSec have a return type of void. Results are thus to be returned through its formal arguments of type pointer to int and pointer to double (in the case of seconds Sec, which might have fractional part).
Calling the conversion in C might be done like this:
double longitude = -119.8374747;
int Sign, Degrees, Minutes;
double Seconds;
double2DegMinSec(longitude, &Sign, &Degrees, &Minutes, &Seconds);
In C++ we would make the calling syntax a bit glibber by using call-by-reference instead of pointers.
With just multiplying you'll get conversion errors without noticing it, I noticed it when mapping the points on a map. You'll need to take into account the slope and other variables, like this:
public static void GeoToMercator(double xIn, double yIn, out double xOut, out double yOut)
{
double xArg = xIn / 100000, yArg = yIn / 100000;
xArg = 6371000.0 * Math.PI / 180 * xArg;
yArg = 6371000.0 * Math.Log(Math.Tan(Math.PI / 4 + Math.PI / 180 * yArg * 0.5));
xOut = xArg / 10000;
yOut = yArg / 10000;
}
I'm guessing you're using Mercator values as double representation. To convert the Mercator value back into the correct longitude/latitude values, just use the reverse:
public static void MercatorToGeo(double xIn, double yIn, out double xOut, out double yOut)
{
double xArg = xIn, yArg = yIn;
xArg = 180 / Math.PI * xArg / 6371000.0;
yArg = 180 / Math.PI * (Math.Atan(Math.Exp(yArg / 6371000.0)) - Math.PI / 4) / 0.5;
xOut = xArg * 10;
yOut = yArg * 10;
}
This did the trick for me.

Categories