GPS Co-ordinates conversion - gps

I'm trying to find out the formula to convert the following GPS location format to a decimal degree format used by Google Maps. I've searched around but I can't figure it out.
My current format is ddmm.mmmm, and my value is 2603.3299 S, 02758.0530 E.
1.) What is my current GPS location is decimal degrees?
2.) What is the formula to convert this into decimal degrees?
Thanks a ton!
The formula I've seen online puts me somewhere in Egypt, but I'm actually in South Africa. Obviously something is wrong :(
Also, please don't assassinate me at this address. I still have lots to do with my life :(

You may shift the decimal point by two places and convert minutes to decimal degrees:
2603.3299 -> 26 + (3.3299 / 60) = 26.0554983
and
2758.0530 -> 27 + (58.0530 / 60) = 27.96755

The problem is with your data.
2603.3299 S, 02758.0530 E
is missing a delimiter and actually means
26 degrees 03.3299 minutes S, 027 degrees 58.0530 minutes E
Assuming you live in a brick house in a city and not in the middle of a field. In which case, it means
26.033299 S, 027.580530 E
Note that 2603.3299 S, 02758.0530 E doesn't seem to be a standard notation.
Split the last two digits before the decimal point as a minute figure and divide by 60. In javascript:
var split/(^\d+)(\d\d\.\d+$)/.match(x);
return split[1]+split[2]/60;

Related

How would i separate an answer in Kotlin do print 2 different types

Hi this is my first ever program I'm tryin to write in android studio/Kotlin and I'm not sure how to proceed.
so in my program i have a few math tasks to do and it does it fine but what I need to do now is separate part of the answer then covert it then print out both parts
for example if my answer was 1.5232 i would like to convert the decimal part of the answer to a string that matches a range if its in it. the ranges I have are in the .0000 area so I would like to limit the decimal range too.
so final result would look like this
1 (whatever my string in range is)
I hope I included enough info thank you in advance.
The first part of the task is to split the number into the integer and fractional components:
val input = 1.5232
val integer = input.toInt() // rounds DOWN to nearest smaller Int
val fractional = input % 1.0 // The remainder when dividing by 1.0 is the fraction
The strategy I would use to round to the nearest fractional value given a certain precision is to multiply by that precision, and round to the nearest integer. That would give you the numerator, and the precision would be the denominator:
val denominator = 8 // fractional precision
val numerator = (fractional * denominator).roundToInt() // rounds up or down to nearest Int
Then to put it together, you can use a string template:
val result = "$integer $numerator/$denominator"
println(result)
Simplifying the fraction would be another task if you need that. You can find various algorithms for finding greatest common divisor of two numbers. Use one of those and divide the numerator and denominator by that value.

SAS TO COBOL conversion variable declaration

Friends,
I am doing SAS to COBOL conversion.I am stuck with below declaration and conversion.So I am getting SOC7 in COBOL run.Please provide some solution.
IP in SAS - PD3.5
OP in SAS - z6.5
My COBOL declaration below.
IP s9.9(5);
OP .9(5);
Please suggest some solution..
Thanks a lot!!
Packed Decimal is stored one digit per nibble, which is two digits per byte, with the last nibble storing the sign. The sign nibbles C, A, F, and E are treated as positive; the sign nibbles B and D are treated as negative. Sign nibbles C and D are referred to as "preferred sign". A sign nibble of F is considered "unsigned," meaning it is neither positive nor negative, though pragmatically you can think of it as positive for arithmetic purposes. +123 is stored in two bytes as x'123C', -456 is stored as x'456D'.
The SAS PD informat specifies PDw.d where w is the width of the field in bytes and d is the number of decimal places to the right within the field. So PD3.5 is a 3 byte field (which would store 5 digits and a sign) with all 5 digits to the right of the decimal point.
To obtain the COBOL declaration for a SAS PDw.d declaration...
a = (w * 2) - 1
b = a - d
if b = 0
PIC SVd Packed-Decimal
else
PIC S9(b)Vd Packed-Decimal
The SAS Z format specifies Zw.d where w is the width of the field in bytes and d is the number of decimal places to the right within the field. The field will be padded with zeroes on the left to make it w bytes wide. So Z6.5 specifies a 6 byte output field with 5 bytes to the right of the decimal point. One byte is taken by the decimal point itself, and unfortunately there is no room for the sign, which may be a bug or may be intentional (perhaps all the data is known to be positive).
IP PIC Sv99999 Packed-Decimal.
OP PIC .99999.
When you MOVE IP TO OP the conversion from Packed Decimal to Zoned Decimal will be done for you by COBOL.

whats the best datatype to store height?

Pretty straight forward question, I want to store feet and inches in 1 column using a decimal, but I dont want it truncated like how the float type does.
Store all your data in MKS (metric). When presenting and storing convert the data into an international standard. and store it in a decimal type.
Thus if your tool to gather the data is in 6'2" format convert it into cm and save in your data table. Then reverse this for display.
By saving in a standard format decimal cm. finding people with the same range of height is easier, where as if Ft and In are in separate columns ranges are really hard.
The imperial unit system still used in Myanmar, Liberia and that one country in North America is unfortunately not very arithmetics-friendly. There is no native data-type to handle the strange base12/base3/base1860 math for it.
You should really use the much more widely-used metric system and use a FLOAT or DECIMAL value representing meters.
However, when you really want to stay with the imperial system, you should store the value in inch and do the conversation to feet + inch on the GUI level.
Decimal lets you store an exact precision.
The question is if you want to store it in feet or inches.
If inches then:
feet * 12 + inches
If feet then:
feet + (inches / 12)
If inches the conversion back
declare #inches dec(8,4)
declare #indesinfoot as dec(8,4);
set #indesinfoot = 12;
set #inches = (12*#indesinfoot) + 6.25;
print #inches;
SELECT cast(#inches/#indesinfoot as Int) as feet,
inches % #indesinfoot AS inches;
I would go with inches as you can get some rounding error with division but not with multiplication.
Use DECIMAL Data type
It lets you specify the precision you need for your specific needs, without truncating like FLOAT
NUMERIC() or DECIMAL() will work for a single column answer, but you'll need to decide if you're storing feet or inches. These fields use precise math and accurate storage.
If you must store feet and inches, you'll need to either define your own datatype (which is fairly complicated) or use two NUMERIC() or DECIMAL() fields.
Not that you'd ever run into precision problems with feet or inches with FLOAT when measuring something the size of a human being. You'd be off by a hair. Literally.
Example procedure to convert the old English system to metric. No error checking but it will give you an idea how to convert data as entered into data for storage.
CREATE PROCEDURE usp_ConvertHeight
#Input varchar(10)
AS
BEGIN
DECLARE
#FT AS DECIMAL(18,10) = 0,
#IN AS DECIMAL(18,10) = 0,
#CM AS DECIMAL(18,10)
SELECT #FT = CAST(left(#Input,CHARINDEX('''',#Input,1) - 1) AS DECIMAL(18,10));
SELECT #IN = CAST(REPLACE(SUBSTRING(#Input,CHARINDEX('''',#Input,1) + 1,10),'"','')AS DECIMAL(18,10));
SET #CM = 2.54 * ((12 * #FT) + #IN);
SELECT #CM
END
I suggest to store the data in single unit,either inches or in cm.
Ideally give the user option to enter it in any format. Convert and show the user information in all the possible units like in feets and inches and cm.

How do you multiply two fixed point numbers?

I am currently trying to figure out how to multiply two numbers in fixed point representation.
Say my number representation is as follows:
[SIGN][2^0].[2^-1][2^-2]..[2^-14]
In my case, the number 10.01000000000000 = -0.25.
How would I for example do 0.25x0.25 or -0.25x0.25 etc?
Hope you can help!
You should use 2's complement representation instead of a seperate sign bit. It's much easier to do maths on that, no special handling is required. The range is also improved because there's no wasted bit pattern for negative 0. To multiply, just do as normal fixed-point multiplication. The normal Q2.14 format will store value x/214 for the bit pattern of x, therefore if we have A and B then
So you just need to multiply A and B directly then divide the product by 214 to get the result back into the form x/214 like this
AxB = ((int32_t)A*B) >> 14;
A rounding step is needed to get the nearest value. You can find the way to do it in Q number format#Math operations. The simplest way to round to nearest is just add back the bit that was last shifted out (i.e. the first fractional bit) like this
AxB = (int32_t)A*B;
AxB = (AxB >> 14) + ((AxB >> 13) & 1);
You might also want to read these
Fixed-point arithmetic.
Emulated Fixed Point Division/Multiplication
Fixed point math in c#?
With 2 bits you can represent the integer range of [-2, 1]. So using Q2.14 format, -0.25 would be stored as 11.11000000000000. Using 1 sign bit you can only represent -1, 0, 1, and it makes calculations more complex because you need to split the sign bit then combine it back at the end.
Multiply into a larger sized variable, and then right shift by the number of bits of fixed point precision.
Here's a simple example in C:
int a = 0.25 * (1 << 16);
int b = -0.25 * (1 << 16);
int c = (a * b) >> 16;
printf("%.2f * %.2f = %.2f\n", a / 65536.0, b / 65536.0 , c / 65536.0);
You basically multiply everything by a constant to bring the fractional parts up into the integer range, then multiply the two factors, then (optionally) divide by one of the constants to return the product to the standard range for use in future calculations. It's like multiplying prices expressed in fractional dollars by 100 and then working in cents (i.e. $1.95 * 100 cents/dollar = 195 cents).
Be careful not to overflow the range of the variable you are multiplying into. Your constant might need to be smaller to avoid overflow, like using 1 << 8 instead of 1 << 16 in the example above.

in VB Why (1 = 1) is False

I just came across this piece of code:
Dim d As Double
For i = 1 To 10
d = d + 0.1
Next
MsgBox(d)
MsgBox(d = 1)
MsgBox(1 - d)
Can anyone explain me the reason for that? Why d is set to 1?
Floating point types and integer types cannot be compared directly, as their binary representations are different.
The result of adding 0.1 ten times as a floating point type may well be a value that is close to 1, but not exactly.
When comparing floating point values, you need to use a minimum value by which the values can differ and still be considered the same value (this value is normally known as the epsilon). This value depends on the application.
I suggest reading What Every Computer Scientist Should Know About Floating-Point Arithmetic for an in-depth discussion.
As for comaring 1 to 1.0 - these are different types so will not compare to each other.
.1 (1/10th) is a repeating fraction when converted to binary:
.0001100110011001100110011001100110011.....
It would be like trying to show 1/3 as a decimal: you just can't do it accurately.
This is because a double is always only an approximation of the value and not the exact value itself (like a floating point value). When you need an exact decimal value, instead use a Decimal.
Contrast with:
Dim d As Decimal
For i = 1 To 10
d = d + 0.1
Next
MsgBox(1)
MsgBox(d = 1)
MsgBox(1 - d)