LinuxQuestions.org

LinuxQuestions.org (/questions/)
-   Programming (https://www.linuxquestions.org/questions/programming-9/)
-   -   Simple Arithmetic Program (help pls) (https://www.linuxquestions.org/questions/programming-9/simple-arithmetic-program-help-pls-767803/)

MaGicMaX 11-08-2009 09:06 PM

Simple Arithmetic Program (help pls)
 
I have a simple mathematical process i would like to automate with a program of some sort. Maybe even a basic shell script. I would like to have the user specify (or be prompted for) a few variables "A" "B" "C" and "M". Where A,B, and C are values in units of time aka HMS (hh.mmss). And M is in units of MiB.

A+B+C=TT (in HMS, whats the syntax for adding HMS units in the shell?)

A HMS-> / TT HMS-> = AX (unitless factor)

Where "HMS->" (aka HMS OUT) means to convert HMS to a decimal number (unitless).

And repeat for B and C, resulting in AX,BX, and CX.

Then simply:

AX*M=AS (in MiB)
BX*M=BS (in MiB)
CX*M=CS (in MiB)

The desired output would be the numerical values of AS,BS, and CS.

I know theres probably many ways to do this, any suggestions would be helpful. To keep it simple i would prefer a simple bash script if possible.

chrism01 11-09-2009 12:43 AM

For a start, reduce/cvt all time units to the lowest ie seconds.

You should read/bookmark these
http://rute.2038bug.com/index.html.gz
http://tldp.org/LDP/Bash-Beginners-G...tml/index.html
http://www.tldp.org/LDP/abs/html/

Note that shell only works in integers, so you'll get rounding or truncation when doing division. If you want floating pt, use the bc tool http://linux.die.net/man/1/bc

salasi 11-09-2009 08:35 AM

Quote:

Originally Posted by MaGicMaX (Post 3749820)
are values in units of time aka HMS (hh.mmss). And M is in units of MiB.

A+B+C=TT (in HMS, whats the syntax for adding HMS units in the shell?)

...To keep it simple i would prefer a simple bash script if possible.

The shell (bash) has no data type for time in h:m:s, so if you want to do it with the shell you will have to do all of the management of this datatype yourself.

Actually, nor do most programming languages have an h:m:s datatype inherently, but in some you could happily define an object to have one, and that may make things easier/cleaner.

Also the problem that chrism01 mentions:
Quote:

shell only works in integers... If you want floating pt, use the bc tool
I've never really managed to get on with BC; I'm sure many like it (but not me) and I'd be happier to use a scripting language like python. YMMV, just be aware of deciding 'in advance' (without having thought through all of the issues) of deciding on a particular approach 'to make things simpler' if that approach ends up making things harder.

pixellany 11-09-2009 08:39 AM

I've seen some posts lately about floating-point math with AWK (I'm not an "AWK person" myself, no first-hand knowledge....)

archtoad6 11-09-2009 10:50 AM

FWIW,
Code:

echo $(($(echo "((1:20:5" |sed 's,:,)*60+,g')))
will convert hh:mm:ss to seconds, provided "hh:" is present & positive (it can of course be 0). Substitute your time value for my "1:20:5" test case. That takes care of your 1st step:
A+B+C=TT

To do decimals for
A HMS-> / TT HMS-> = AX
you must append a 0 (* 10^N) for each decimal place you want. If you want to display the resulting factors, you will need to clean up your output by inserting a decimal point in the correct spot.

You should leave the factors as is for the next step
AX*M=AS (in MiB)
BX*M=BS (in MiB)
CX*M=CS (in MiB)
& divide your results by 10^N.

To me this seems like an easy bash script. I think qualifying the inputs may be more difficult than the arithmetic.

Edit: Changed "1^N" to "10^N"

MaGicMaX 11-09-2009 08:50 PM

Quote:

Originally Posted by archtoad6 (Post 3750433)
FWIW,
Code:

echo $(($(echo "((1:20:5" |sed 's,:,)*60+,g')))
will convert hh:mm:ss to seconds, provided "hh:" is present & positive (it can of course be 0). Substitute your time value for my "1:20:5" test case. That takes care of your 1st step:
A+B+C=TT

To do decimals for
A HMS-> / TT HMS-> = AX
you must append a 0 (* 1^N) for each decimal place you want. If you want to display the resulting factors, you will need to clean up your output by inserting a decimal point in the correct spot.

You should leave the factors as is for the next step
AX*M=AS (in MiB)
BX*M=BS (in MiB)
CX*M=CS (in MiB)
& divide your results by 1^N.

To me this seems like an easy bash script. I think qualifying the inputs may be more difficult than the arithmetic.

Your first step for reducing HMS to seconds is great, works perfect, thanks. If i do that, then i can save those values as A,B and C (overwriting original user inputs in HMS). Then, simply sum them to get TT (in seconds is fine). If i leave A and TT in seconds i will still get a unitless factor. As far as decimal places, 12 is fine. Im not sure i understand why or how i need to append to do this, why will it need to be cleaned up exactly? Sorry im not very experienced doing even simple arithmetic in the shell. How would i divide them, then append them (the command/syntax)?

I guess my first step before trying to write a scrip is figuring how to even do it manually in the shell first. So now i can convert HMS to seconds and get TT in seconds. Now i just need to divide each A,B, and C by TT and get a factor to 12 decimal places (AX,BX,CX). Then just multiply AX,BX, and CX by "M", to the nearest whole number is fine.

PS: Is there a source for that "echo $(($(echo "((1:20:5" |sed 's,:,)*60+,g')))" command i could read over, just curious what each piece means exactly (how it works).

archtoad6 11-10-2009 07:27 AM

Quote:

Originally Posted by MaGicMaX (Post 3751032)
Im not sure i understand why or how i need to append to do this, why will it need to be cleaned up exactly? Sorry im not very experienced doing even simple arithmetic in the shell. How would i divide them, then append them (the command/syntax)?

Remember --
Quote:

Originally Posted by chrism01 (Post 3749944)
...Note that shell only works in integers, so you'll get rounding or truncation when doing division. ...

i.e. rounding or truncation errors if you don't append & clean up. Multiply by 10^12 at the beginning & either insert a decimal point or divide by 10^12 at the end.


Quote:

Originally Posted by MaGicMaX (Post 3751032)
I guess my first step before trying to write a scrip is figuring how to even do it manually in the shell first. So now i can convert HMS to seconds and get TT in seconds.

Definitely a good way to proceed.


Quote:

Originally Posted by MaGicMaX (Post 3751032)
Now i just need to divide each A,B, and C by TT and get a factor to 12 decimal places (AX,BX,CX). Then just multiply AX,BX, and CX by "M", to the nearest whole number is fine.

As long as you make the correct adjustments for the integer arithmetic limitations of bash.


Quote:

Originally Posted by MaGicMaX (Post 3751032)
PS: Is there a source for that "echo $(($(echo "((1:20:5" |sed 's,:,)*60+,g')))" command i could read over, just curious what each piece means exactly (how it works).

There are 2, 3, or 4 sources, depending on how you count: Here are my original & a simpler version colored to highlight the syntax:
Code:

echo $(($(echo "((1:20:5" | sed 's,:,)*60+,g')))
echo  $[ `echo "((1:20:5" | sed 's,:,)*60+,g'`]    # deprecated but simpler form

Once you have read A, B, or C into your script (& checked them for errors) you can process them from hh:mm:ss into seconds:
Code:

echo $(($(echo "(($A" | sed 's,:,)*60+,g')))
echo  $[ `echo "(($A" | sed 's,:,)*60+,g'`]    # deprecated but simpler form

We know that either
(hh*60+mm)*60+ss
or, adding a set of mathematically unnecessary, but programatically useful parentheses
((hh)*60+mm)*60+ss
will convert hh:mm:ss into seconds, so the innermost (purple hues) echo adds the 2 necessary leading parentheses to the hh:mm:ss & pipes it into a sed which turns the colons into the right math. Run
Code:

echo "((1:20:5"  | sed 's,:,)*60+,g'
to see that this is true.

The Command Substitution
$( ... ) or
` ... `
makes the algebra available to the Arithmetic Expansion
$(( ... )) or
$[ ... ]
The green (1st) echo displays the result of the Arithmetic Expansion, you may not need it in your script.


It's time for you to start working on the commands. Post them & we'll critique them.

MaGicMaX 11-10-2009 07:24 PM

Thanks for the detailed response. I think going with a bash scrip might not be as "simple" as i expected. Perhaps going with a programmable (preferably RPN) calculator program (either CLI or GUI) would be an easier way. I planned to automate some other tasks that i may have more trouble with using a bash script. My background in programming calculators began with HP50g, which uses a HP-Basic language. Where a program is basically stored as a global variable and executed as such. A simple one would look like this:

<< A B C + + D 'STO' D "The Answer Is" ->Tag >>

In RPN mode, it would sum A,B and C, store it as a global variable "D" and display the answer on the stack tagged with "The Answer Is". The above program could be saved as global variable "ABCD", and executed by running ABCD. This is the simplicity i was after :).

I've since opened another thread regarding suggestions for RPN programmable calculators here.

archtoad6 11-15-2009 08:09 AM

<OT>
I started w/ a 35 w/ no model # on the case, went on to the 65, the 97, & a 41 -- which languishes needing a battery because there is no room for both it & my phone in my shirt pocket.
So why doesn't HP, alone or w/ Nokia, make the "perfect" engineer/geek phone? Start w/ the shape (from the Wikipedia® article referenced above):
Quote:

... but William Hewlett saw additional opportunities if the desktop calculator could be made small enough to fit into his shirt pocket. He charged his engineers with this exact goal (to the point that they measured his shirt pocket!).
</OT>


Quote:

<< A B C + + D 'STO' D "The Answer Is" ->Tag >>
I hope 'A', 'B', & 'C' aren't your original variables in HMS, because you still need to convert them. Either that or pretend that they are angles in degrees & maybe trick the calculator into adding them correctly. I think it was the conversion that added the complexity that you "choked on". I remember keying HMS #'s into my HPs as "hh0mm0ss" for addition, & using '940', '940940', or '940000' to make the carries work right.

On a pure keystoke RPN calculator the conversion sequence is: HÎ60*M+60*S+ ('Î' is the "Enter" key).

MaGicMaX 11-15-2009 01:14 PM

Quote:

Originally Posted by archtoad6 (Post 3757748)
<OT>
I started w/ a 35 w/ no model # on the case, went on to the 65, the 97, & a 41 -- which languishes needing a battery because there is no room for both it & my phone in my shirt pocket.
So why doesn't HP, alone or w/ Nokia, make the "perfect" engineer/geek phone? Start w/ the shape (from the Wikipedia® article referenced above): </OT>


I hope 'A', 'B', & 'C' aren't your original variables in HMS, because you still need to convert them. Either that or pretend that they are angles in degrees & maybe trick the calculator into adding them correctly. I think it was the conversion that added the complexity that you "choked on". I remember keying HMS #'s into my HPs as "hh0mm0ss" for addition, & using '940', '940940', or '940000' to make the carries work right.

On a pure keystoke RPN calculator the conversion sequence is: HÎ60*M+60*S+ ('Î' is the "Enter" key).

In my example i was not assuming the variables to be in HMS, just showing the simple syntax for writing a basic program. HP does have "->HSM" and "HMS->", functions to convert to and out of HMS, but short of that, it can be done manually too (in the program).

chrism01 11-16-2009 12:21 AM

Quote:

I planned to automate some other tasks that i may have more trouble with using a bash script.
Depends exactly what you mean here, but for fiddly automation I highly recommend Perl. As an example, its got several built in modules for date calculations.
http://perldoc.perl.org/
http://www.perlmonks.org/?node=Tutorials


All times are GMT -5. The time now is 12:31 AM.