LinuxQuestions.org
LinuxAnswers - the LQ Linux tutorial section.
Go Back   LinuxQuestions.org > Forums > Non-*NIX Forums > Programming
User Name
Password
Programming This forum is for all programming questions.
The question does not have to be directly related to Linux and any language is fair game.

Notices

Reply
 
Search this Thread
Old 11-08-2009, 09:06 PM   #1
MaGicMaX
Member
 
Registered: Aug 2009
Location: Calgary, AB, Canada
Distribution: Ubuntu
Posts: 51

Rep: Reputation: 15
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.
 
Old 11-09-2009, 12:43 AM   #2
chrism01
Guru
 
Registered: Aug 2004
Location: Sydney
Distribution: Centos 6.5, Centos 5.10
Posts: 16,261

Rep: Reputation: 2028Reputation: 2028Reputation: 2028Reputation: 2028Reputation: 2028Reputation: 2028Reputation: 2028Reputation: 2028Reputation: 2028Reputation: 2028Reputation: 2028
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
 
Old 11-09-2009, 08:35 AM   #3
salasi
Senior Member
 
Registered: Jul 2007
Location: Directly above centre of the earth, UK
Distribution: SuSE, plus some hopping
Posts: 3,896

Rep: Reputation: 774Reputation: 774Reputation: 774Reputation: 774Reputation: 774Reputation: 774Reputation: 774
Quote:
Originally Posted by MaGicMaX View Post
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.
 
Old 11-09-2009, 08:39 AM   #4
pixellany
LQ Veteran
 
Registered: Nov 2005
Location: Annapolis, MD
Distribution: Arch/XFCE
Posts: 17,802

Rep: Reputation: 728Reputation: 728Reputation: 728Reputation: 728Reputation: 728Reputation: 728Reputation: 728
I've seen some posts lately about floating-point math with AWK (I'm not an "AWK person" myself, no first-hand knowledge....)
 
Old 11-09-2009, 10:50 AM   #5
archtoad6
Senior Member
 
Registered: Oct 2004
Location: Houston, TX (usa)
Distribution: MEPIS, Debian, Knoppix,
Posts: 4,727
Blog Entries: 15

Rep: Reputation: 230Reputation: 230Reputation: 230
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"

Last edited by archtoad6; 11-10-2009 at 07:32 AM. Reason: typo 1^N should be 10^N
 
Old 11-09-2009, 08:50 PM   #6
MaGicMaX
Member
 
Registered: Aug 2009
Location: Calgary, AB, Canada
Distribution: Ubuntu
Posts: 51

Original Poster
Rep: Reputation: 15
Quote:
Originally Posted by archtoad6 View Post
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).
 
Old 11-10-2009, 07:27 AM   #7
archtoad6
Senior Member
 
Registered: Oct 2004
Location: Houston, TX (usa)
Distribution: MEPIS, Debian, Knoppix,
Posts: 4,727
Blog Entries: 15

Rep: Reputation: 230Reputation: 230Reputation: 230
Quote:
Originally Posted by MaGicMaX View Post
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 View Post
...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 View Post
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 View Post
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 View Post
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.
 
Old 11-10-2009, 07:24 PM   #8
MaGicMaX
Member
 
Registered: Aug 2009
Location: Calgary, AB, Canada
Distribution: Ubuntu
Posts: 51

Original Poster
Rep: Reputation: 15
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.
 
Old 11-15-2009, 08:09 AM   #9
archtoad6
Senior Member
 
Registered: Oct 2004
Location: Houston, TX (usa)
Distribution: MEPIS, Debian, Knoppix,
Posts: 4,727
Blog Entries: 15

Rep: Reputation: 230Reputation: 230Reputation: 230
<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).
 
Old 11-15-2009, 01:14 PM   #10
MaGicMaX
Member
 
Registered: Aug 2009
Location: Calgary, AB, Canada
Distribution: Ubuntu
Posts: 51

Original Poster
Rep: Reputation: 15
Quote:
Originally Posted by archtoad6 View Post
<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).
 
Old 11-16-2009, 12:21 AM   #11
chrism01
Guru
 
Registered: Aug 2004
Location: Sydney
Distribution: Centos 6.5, Centos 5.10
Posts: 16,261

Rep: Reputation: 2028Reputation: 2028Reputation: 2028Reputation: 2028Reputation: 2028Reputation: 2028Reputation: 2028Reputation: 2028Reputation: 2028Reputation: 2028Reputation: 2028
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
 
  


Reply


Thread Tools Search this Thread
Search this Thread:

Advanced Search

Posting Rules
You may not post new threads
You may not post replies
You may not post attachments
You may not edit your posts

BB code is On
Smilies are On
[IMG] code is Off
HTML code is Off


Similar Threads
Thread Thread Starter Forum Replies Last Post
Simple arithmetic using expr mmahulo Linux - Newbie 8 12-23-2008 01:48 AM
QUAINT !!! is this a gcc bug ? pls check out this simple C program.() cryincold Programming 9 02-09-2008 02:43 AM
BASH, simple arithmetic helptonewbie Programming 9 01-10-2007 05:53 PM
simple arithmetic in bash gfrair Linux - Newbie 9 03-16-2005 02:09 PM


All times are GMT -5. The time now is 04:03 AM.

Main Menu
My LQ
Write for LQ
LinuxQuestions.org is looking for people interested in writing Editorials, Articles, Reviews, and more. If you'd like to contribute content, let us know.
Main Menu
Syndicate
RSS1  Latest Threads
RSS1  LQ News
Twitter: @linuxquestions
identi.ca: @linuxquestions
Facebook: linuxquestions Google+: linuxquestions
Open Source Consulting | Domain Registration