You are not logged in.
I didn't realize how troublesome floating point numbers can be until now.
What I want to do should be simple I dare say:
properRounding( ( currentTime - downloadTime ) / ( dueTime - downloadTime ) * 100 )
however best I've been able to achieve so far is this:
echo "($currentTime-$downloadTime)/($dueTime-$downloadTime)*100" | bc -l
Which prints the correct floating point value.
I've tried to put the result in a variable, but I must be doing it wrong as I get the most peculiar error. I can live without it, but it would make life easier.
As for the rounding, that is a must. I've read that if you remove the -l param from bc, then it will round, but in my case something goes wrong as I just get the value 0 in return and besides, concluded after a simple test, bc always rounds down as in integer division, which I can not use.
So of course I'll continue reading and hopefully someday arrive at a solution, but I would very much appreciate if someone could lend me a hand.
This after all is not just a learning experience, I'm trying to create something useful.
Best regards.
edit:
nb:
all variables are integers.
Last edited by zacariaz (2012-09-09 14:50:18)
I am a philosopher, of sorts, not a troll or an imbecile.
My apologies that this is not always obvious, despite my best efforts.
Offline
You'll indeed have to use bc, or dc.
You have to set the scale (e.g. 3k / scale=3) for both programs to show decimals:
echo 3k 20000 19000 - 26000 29000 - / 100 \* f | dc
{ echo scale=3; echo "(20000 - 19000) / (26000 - 29000) * 100"; } | bc
Offline
Didn't know about dc, that I'll have to investigate as I prefer to use the standard tools.
'scale' however don't solve my problem, take for example:
{ echo scale=n; 2 / 3"; } | bc
for n 0 the result should be 1.
for 1 it should be .7
for to .67
etc.
the same goes when using dc of curse.
I am a philosopher, of sorts, not a troll or an imbecile.
My apologies that this is not always obvious, despite my best efforts.
Offline
Googling around a bit, I found you need to divide by 1. But in this case you also need to do the first division in high scale, and add 5 to the decimal place one before the one you want to round at.
echo "scale=5; div=1/3; scale=0; (div+0.5)/1" | bc
echo "scale=5; div=2/3; scale=1; (div+0.05)/1" | bc
echo 5k 2 3 / 0k 0.5 + 1 / f | dc
echo 5k 2 3 / 1k 0.05 + 1 / f | dc
Last edited by Procyon (2012-09-09 13:55:19)
Offline
Googling around a bit, I found you need to divide by 1. But in this case you also need to do the first division in high scale, and add 5 to the decimal place one before the one you want to round at.
echo "scale=5; div=1/3; scale=0; (div+0.5)/1" | bc
echo "scale=5; div=2/3; scale=1; (div+0.05)/1" | bc
echo 5k 2 3 / 0k 0.5 + 1 / f | dc
echo 5k 2 3 / 1k 0.05 + 1 / f | dc
I was about to reply how extremely confusing this is, when I suddenly realized that isn't the case at all.
Thanks once again.
I am a philosopher, of sorts, not a troll or an imbecile.
My apologies that this is not always obvious, despite my best efforts.
Offline
Well, I'm afraid I'm not quit out of the woods yet, especially with the 'dc' command.
echo 3k $currentTime $downloadTime - $dueTime $downloadTime - / 100 \* 0.5 + f | dc
The above prints the correct value with what looks to be a precision of 3, but really the precision is 1 with 2 trailing zeros.
Is it now I should mention that I'm not a fan of the stack?
In any case, I could probably get it to work with the 'bc' command, but as mentioned earlier, I would rather like to use the 'dc' command.
I have of course read the man page and tried to comprehend what you've posted, but frankly it hasn't helped much. Regardless of what I do, it just won't work.
edit:
Actually I may just have figured it out:
echo 3k $currentTime $downloadTime - $dueTime $downloadTime - / 100 \* 0k 0.5 + 1 / f | dc
It was the divide by one I forgot.
Also I just realized that dc comes with bc - doh.
edit:
Everything works!
Thanks a bunch.
Last edited by zacariaz (2012-09-09 14:49:55)
I am a philosopher, of sorts, not a troll or an imbecile.
My apologies that this is not always obvious, despite my best efforts.
Offline
The scale is 3 when you do the division.
2/3 = 0.666 (3 decimals)
100 * 0.666 = 66.600 (3 decimals)
Notice that I changed the scale halfway through, and the division by 1 at the end to apply the scale.
echo 10k 2 3 / 100 \* 3k 0.0005 + 1/ f| dc
Offline
Just for the fun of it, here's my progress thus far... Well, there really isn't much more to do. The rest is a conky thing.
#!/bin/bash
# Variables from unitinfo.txt - date as unix timestamps.
dueTime="$(date +%s -d "$(grep 'Due time: ' ~/unitinfo.txt | cut -c11-)")"
if [ "$1" = "end" ]
then echo $dueTime
fi
downloadTime="$(date +%s -d "$(grep 'Download time: ' ~/unitinfo.txt | cut -c16-)")"
if [ "$1" = "start" ]
then echo $downloadTime
fi
progress="$(grep 'Progress: ' ~/unitinfo.txt | cut -c11-12 | sed 's/ *$//')"
if [ "$1" = "prog1" ]
then echo $progress
fi
# The rest
#progress valued 0-1 for use with conky proress bars
progress2=$( echo 2k $progress 100 / f | dc )
if [ "$1" = "prog2" ]
then echo $progress2
fi
# Current time - unix timestamp.
currentTime="$(date +%s)"
# Remaining time - unix timestamp
remainingTime=$(( dueTime-$currentTime ))
if [ "$1" = "remain" ]
then echo $remainingTime
fi
# Elapsed time - unix timestamp
elapsedTime=$(( currentTime-downloadTime ))
if [ "$1" = "elap1" ]
then echo $elapsedTime
fi
# Total amount of time available - unix timestamp
totalTime=$(( dueTime-downloadTime ))
if [ "$1" = "total" ]
then echo $totalTime
fi
# How much time has elapsed in percent
progress3="$(echo 3k $elapsedTime $totalTime / 100 \* 0k 0.5 + 1 / f | dc)"
if [ "$1" = "elap2" ]
then echo $progress3
fi
# Like the above bur 0-1
progress4=$( echo 2k $progress3 100 / f | dc )
if [ "$1" = "elap3" ]
then echo $progress4
fi
# In percent, expected completion vs $dueTime - less than 100 is better.
expectedCompletion="$( echo 3k $elapsedTime 10000 \* $progress / $totalTime / 0k 0.5 + 1 / f | dc )"
if [ "$1" = "exp1" ]
then echo $expectedCompletion
fi
# Same as above, but unix timestamp
expectedCompletion2=$(( downloadTime+(expectedCompletion*totalTime/100) ))
if [ "$1" = "exp2" ]
then echo $expectedCompletion2
fi
#efficiency
if [ "$1" = "ef1" ]; then
if [ $progress -lt $progress3 ]
then echo "you're behind schedule."
elif [ $progress -eq $progress3 ]
then echo "You're right on schedule."
else
echo "You're ahead of schedule."
fi
fi
if [ "$1" = "ef2" ]; then
if [ $expectedCompletion -gt 100 ]
then echo "You're not going to make it!"
else
echo "You're going to make it!"
fi
fi
I am a philosopher, of sorts, not a troll or an imbecile.
My apologies that this is not always obvious, despite my best efforts.
Offline