I'm having a hard time on thinking what should I do with this problem. I'm dividing the two numbers and expecting a non-whole number answer. Meaning to say it should be on decimal format. But unfortunately it answers a whole number.
example: 5 / 2 = 2
s.apts = sum_pts.to_f / sum_game.to_f
You just need to tell Ruby you are doing non-integer division, by writing the problem as "5.0 / 2.0"
See:
Why is division in Ruby returning an integer instead of decimal value?
Try this:
a = 5.0
b = 2.0
puts a / b
Related
I'm relatively new to Z3 and experimenting with it in python. I've coded a program which returns the order in which different actions is performed, represented with a number. Z3 returns an integer representing the second the action starts.
Now I want to look at the model and see if there is an instance of time where nothing happens. To do this I made a list with only 0's and I want to change the index at the times where each action is being executed, to 1. For instance, if an action start at the 5th second and takes 8 seconds to be executed, the index 5 to 12 would be set to 1. Doing this with all the actions and then look for 0's in the list would hopefully give me the instances where nothing happens.
The problem is: I would like to write something like this for coding the problem
list_for_check = [0]*total_time
m = s.model()
for action in actions:
for index in range(m.evaluate(action.number) , m.evaluate(action.number) + action.time_it_takes):
list_for_check[index] = 1
But I get the error:
'IntNumRef' object cannot be interpreted as an integer
I've understood that Z3 isn't returning normal ints or bools in their models, but writing
if m.evaluate(action.boolean):
works, so I'm assuming the if is overwritten in a way, but this doesn't seem to be the case with range. So my question is: Is there a way to use range with Z3 ints? Or is there another way to do this?
The problem might also be that action.time_it_takes is an integer and adding a Z3int with a "normal" int doesn't work. (Done in the second part of the range).
I've also tried using int(m.evaluate(action.number)), but it doesn't work.
Thanks in advance :)
When you call evaluate it returns an IntNumRef, which is an internal z3 representation of an integer number inside z3. You need to call as_long() method of it to convert it to a Python number. Here's an example:
from z3 import *
s = Solver()
a = Int('a')
s.add(a > 4);
s.add(a < 7);
if s.check() == sat:
m = s.model()
print("a is %s" % m.evaluate(a))
print("Iterating from a to a+5:")
av = m.evaluate(a).as_long()
for index in range(av, av + 5):
print(index)
When I run this, I get:
a is 5
Iterating from a to a+5:
5
6
7
8
9
which is exactly what you're trying to achieve.
The method as_long() is defined here. Note that there are similar conversion functions from bit-vectors and rationals as well. You can search the z3py api using the interface at: https://z3prover.github.io/api/html/namespacez3py.html
I'm trying to find the decimal value from a percentage that a user inputs.
For example, if a user inputs "15", i will need to do a calculation of 0.15 * number.
I've tried using .to_f, but it returns 15.0:
15.to_f
#=> 15.0
I also tried to add 0. to the beginning of the percentage, but it just returns 0:
15.to_s.rjust(4, "0.").to_i
#=> 0
Divide by 100.0
The easiest way to do what you're trying to do is to divide your input value by a Float (keeping in mind the inherent inaccuracy of floating point values). For example:
percentage = 15
percentage / 100.0
#=> 0.15
One benefit of this approach (among others) is that it can handle fractional percentages just as easily. Consider:
percentage = 15.6
percentage / 100.0
#=> 0.156
If floating point precision isn't sufficient for your use case, then you should consider using Rational or BigDecimal numbers instead of a Float. Your mileage will very much depend on your semantic intent and accuracy requirements.
Caveats
Make sure you have ahold of a valid Integer in the first place. While others might steer you towards String#to_i, a more robust validation is to use Kernel#Integer so that an exception will be raised if the value can't be coerced into a valid Integer. For example:
print "Enter integer: "
percentage = Integer gets
If you enter 15\n then:
percentage.class
#=> Integer
If you enter something that can't be coerced to an Integer, like foo\n, then:
ArgumentError (invalid value for Integer(): "foo\n")
Using String#to_i is much more permissive, and can return 0 when you aren't expecting it, such as when called on nil, an empty string, or alphanumeric values that don't start with an integer. It has other interesting edge cases as well, so it's not always the best option for validating input.
I'm trying to find the amount from a percentage that a user inputs
If you retrieve the input via gets, you typically convert it to a numeric value first, e.g.
percentage = gets.to_i
#=> 15
Ruby is not aware that this 15 is a percentage. And since there's no Percentage class, you have to convert it into one of the existing numeric classes.
15% is equal to the fraction 15/100, the ratio 15:100, or the decimal number 0.15.
If you want the number as a (maybe inexact) Float, you can divide it by 100 via fdiv:
15.fdiv(100)
#=> 0.15
If you prefer a Rational you can use quo: (it might also return an Integer)
15.quo(100)
#=> (3/20)
Or maybe BigDecimal for an arbitrary-precision decimal number:
require 'bigdecimal'
BigDecimal(15) / 100
#=> 0.15e0
BigDecimal also accepts strings, so you could pass the input without prior conversion:
input = gets
BigDecimal(input) / 100
#=> 0.15e0
I have a data file where decimal points aren't specified for a decimal number. The number is just described in the layout for the data file as first 2 digits as real and next 2 digits as decimal and it varies for different fields, the real and decimal part
So an actual number 12345.6789 is specified as 123456789. When I want this to be rounded off to 2 decimal points to match the value in application, I use the below logic
Public Function Rounding(NumberValue, DecimalPoints, RoundOff)
Rounder= Roundoff+1
Difference = DecimalPoints - Rounder
NumberValue = Mid(NumberValue, 1, Len(NumberValue)-Difference)
RealNumber=Mid(NumberValue,1,Len(NumberValue)-Rounder)
DecimalNumber=Right(NumberValue,Rounder)
NumberValue = RealNumber&"."&DecimalNumber
NumberValue = Cdbl(NumberValue)
NumberValue = Round(NumberValue, Roundoff)
Rounding = FormatNumber(NumberValue,Difference+1,,,0)
End Function
However the problem with this logic is that I am not able to round off decimals when the number has 0 as the decimal value
For an Example, lets take 12345.0000 which I want to round off to 2 decimal points
My function returns it as 12345 whereas I want this to be returned as 12345.00
Any ideas on how this logic could be tweaked to get the desired output or is that not possible at all?
To get the decimal places, use the Formatnumber function. See http://msdn.microsoft.com/en-us/library/ws343esk(v=vs.84).aspx - the default is normally 2 decimal places, but it is region settings specific when using the defaults.
Your script also has a small issue if the decimalpoints variable matches the roundoff variable - it will not populate Rounding with a result. I am also not sure why you are comparing DecimalPoints to Roundoff (-1) ?
I've revised the entire routine - it should do what you want (although I don't know what values you are feeding it) - So now it will work like this:
Doing 4 digits:
Rounding (123450001, 4, 2)
Result:
12345.00
Doing 2 digits:
Rounding (123450001, 2, 2)
Result:
1234500.01
Doing 4 digits (increments if > .5)
Rounding (876512345678, 8, 4)
Result:
8765.1235
Revised simplified function that should do everything you are asking:
Public Function Rounding(NumberValue, DecimalPoints, RoundOff )
RealNumber = Mid(NumberValue, 1, Len(NumberValue)-DecimalPoints)
DecimalNumber = Round("." & Right(NumberValue,DecimalPoints), RoundOff)
Rounding = FormatNumber(RealNumber + DecimalNumber,RoundOff,,,0)
End Function
Here's a working version of your Function:
Public Function Rounding(NumberValue, DecimalPoints, RoundOff)
RealNumber=left(NumberValue,Len(NumberValue)-DecimalPoints)
DecimalNumber="." & Right(NumberValue,DecimalPoints)
NumberValue = RealNumber + DecimalNumber
NumberValue = Round(NumberValue,RoundOff)
Rounding = FormatNumber(NumberValue, RoundOff,,,0)
End Function
I'm pretty sure you won't be able to use the Round() function for what you need. Take a look at the FormatNumber() or FormatCurrency() functions as they have the option to "IncludeLeadingZero".
Take a look at the answer from the following link for more information:
vbscript round to 2 decimal places using Ccur
like in C and C++
double x
How to do it in ruby ?
Or to be in the type float?
I want to run
x=5/2
then
x=2.5
instead of
x=2
If at least one of the operands is a float, the result will be a float too.
5 / 2.0 # => 2.5
In ruby, you create a float by specifying a decimal point:
2 #=> integer
2.0 #=> float
If you divide an integer by another integer, you get an integer. You have to use a float in the division:
5 / 2 #=> 2
5.0 / 2 #=> 2.5
5 / 2.0 #=> 2.5
Ruby is dynamically typed, so there isn't an explicit way to cast a variable to a specific type. Eg:
a = "a" # here a is a String
a = 5 # now a is a Fixnum
a = 5.0 # now a is a Float
is totally valid.
So what happens when you say 5/2? Ruby looks up the / operator in the first operand, in this case an integer, and then calls the function with the second operand, also an integer. Thus Ruby assumes you want integer division.
The solution is to make one of the operators a float, this can be done in at least two ways:
5 / 2.0
or
5 / 2.to_f
Variables don't have types in Ruby, only objects do. (And the concept of "type" is latent, it is not manifest in the program. The "type" of an object is the protocol it speaks, i.e. the messages it responds to and how it responds to those messages. In particular, the type of an object is not its class.)
By default in ruby all the floats are double according to the source code
To create a float value you have to add .0 to difference from the integers value.
Note: if you use two integers in a one operation by default the result is an integer
5.0 # float
5 # integer
5 / 2 = 2 # integer
5 / 2.0 = 2.5 #float
Float definition on the ruby source code
When we convert a float to integer in visual basic 6.0, how does it round off the fractional part? I am talkin about the automatic type conversion.
If we assign like
Dim i as Integer
i=5.5
msgbox i
What will it print? 5 or 6 ??
I was getting "5" a couple of months before. One day it started giving me 6!
Any idea whats goin wrong? Did microsoft released some patches to fix something?
Update : 5.5 gets converted to 6 but 8.5 to 8 !
Update 2 : Adding CInt makes no difference. CInt(5.5) gives 6 and Cint(8.5) gives 8!! Kinda weired behaviour. I should try something like floor(x + 0.49);
Part of this is in the VB6 help: topic Type Conversion Functions. Unfortunately it's one of the topics that's not in the VB6 documentation on the MSDN website, but if you've installed the help with VB6, it will be there.
When the fractional part is exactly 0.5, CInt and CLng always round it to the nearest even number. For example, 0.5 rounds to 0, and 1.5 rounds to 2. CInt and CLng differ from the Fix and Int functions, which truncate, rather than round, the fractional part of a number. Also, Fix and Int always return a value of the same type as is passed in.
Implicit type coercion - a.k.a. "evil type coercion (PDF)" - from a floating point number to a whole number uses the same rounding rules as CInt and CLng. This behaviour doesn't seem to be documented anywhere in the manual.
If you want to round up when the fractional part is >= 0.5, and down otherwise, a simple way to do it is
n = Int(x + 0.5)
And off the top of my head, here's my briefer version of Mike Spross's function which is a replacement for the VB6 Round function.
'Function corrected, now it works.
Public Function RoundNumber(ByVal value As Currency, Optional PlacesAfterDecimal As Integer = 0) As Currency
Dim nMultiplier As Long
nMultiplier = 10 ^ PlacesAfterDecimal
RoundNumber = Fix(0.5 * Sgn(value) + value * nMultiplier) / CDbl(nMultiplier)
End Function
Sample output:
Debug.Print RoundNumber(1.6) '2'
Debug.Print RoundNumber(-4.8) '-5'
Debug.Print RoundNumber(101.7) '102'
Debug.Print RoundNumber(12.535, 2) '12.54'
Update: After some googling, I came across the following article:
It is not a "bug", it is the way VB was
designed to work. It uses something
known as Banker's rounding which, if
the number ends in exactly 5 and you
want to round to the position in front
of the 5, it rounds numbers down if
the number in front of the 5's
position is even and rounds up
otherwise. It is supposed to protect
against repeated calculation using
rounded numbers so that answer aren't
always biased upward. For more on this
issue than you probably want to know,
see this link
http://support.microsoft.com/default.aspx?scid=KB;EN-US;Q196652
This explains the (apparent) weird behavior:
Cint(5.5) 'Should be 6'
Cint(8.5) 'Should be 8'
Old Update:
Perhaps you should be more explicit: use CInt, instead of simply assigning a float to an integer. E.g:
Dim i as Integer
i = CInt(5.5)
MsgBox i
The changed behaviour sounds worrying indeed, however the correct answer surley is 6. Scroll down to "Round to even method" on Wikipedia, Rounding for an explanation.
As others have already pointed out, the "weird behavior" you're seeing is due to the fact that VB6 uses Banker's Rounding when rounding fractional values.
Update 2 : Adding CInt makes no
difference. CInt(5.5) gives 6 and
Cint(8.5) gives 8!!
That is also normal. CInt always rounds (again using the Banker's Rounding method) before performing a conversion.
If you have a number with a fractional part and simply want to truncate it (ignore the portion after the decimal point), you can use either the Fix or the Int function:
Fix(1.5) = 1
Fix(300.4) = 300
Fix(-12.394) = -12
Int works the same way as Fix, except for the fact that it rounds negative numbers down to the next-lowest negative number:
Int(1.5) = 1
Int(300.4) = 300
Int(-12.394) = -13
If you actually want to round a number according to the rules most people are familiar with, you will have to write your own function to do it. Below is an example rounding that will round up when the fractional part is greater than or equal to .5, and round down otherwise:
EDIT: See MarkJ's answer for a much simpler (and probably faster) version of this function.
' Rounds value to the specified number of places'
' Probably could be optimized. I just wrote it off the top of my head,'
' but it seems to work.'
Public Function RoundNumber(ByVal value As Double, Optional PlacesAfterDecimal As Integer = 0) As Double
Dim expandedValue As Double
Dim returnValue As Double
Dim bRoundUp As Boolean
expandedValue = value
expandedValue = expandedValue * 10 ^ (PlacesAfterDecimal + 1)
expandedValue = Fix(expandedValue)
bRoundUp = (Abs(expandedValue) Mod 10) >= 5
If bRoundUp Then
expandedValue = (Fix(expandedValue / 10) + Sgn(value)) * 10
Else
expandedValue = Fix(expandedValue / 10) * 10
End If
returnValue = expandedValue / 10 ^ (PlacesAfterDecimal + 1)
RoundNumber = returnValue
End Function
Examples
Debug.Print RoundNumber(1.6) '2'
Debug.Print RoundNumber(-4.8) '-5'
Debug.Print RoundNumber(101.7) '102'
Debug.Print RoundNumber(12.535, 2) '12.54'
The VB6 Round() function uses a Banker's Rounding method. MS KB Article 225330 (http://support.microsoft.com/kb/225330) talks about this indirectly by comparing VBA in Office 2000 to Excel's native behavior and describes it this way:
When a number with an even integer ends in .5, Visual Basic rounds the number (down) to the nearest even whole number. [...] This difference [between VBA and Excel] is only for numbers ending in a .5 and is the same with other fractional numbers.
If you need different behavior, I'm afraid you'll have to have to specify it yourself.