I have created an SRSS report that shows height, width, and thickness which was in decimals and I have used custom VB code to convert those decimals to fractions. I am wondering if I can round those decimals in the Custom VB fraction code to get a smaller and appropriate fraction? Any suggestions?
Function GetFraction(ByVal Num As Double) As String
If Num = 0# Then
GetFraction = "None"
Else
Dim WholeNumber As Integer
Dim DecimalNumber As Double
Dim Numerator As Double
Dim Denomenator As Double
Dim a, b, t As Double
WholeNumber = Fix(Num)
DecimalNumber = Num - Fix(Num)
Numerator = DecimalNumber * 10 ^ (Len(CStr(DecimalNumber)) - 2)
Denomenator = 10 ^ (Len(CStr(DecimalNumber)) - 2)
If Numerator = 0 Then
GetFraction = WholeNumber
Else
a = Numerator
b = Denomenator
t = 0
While b <> 0
t = b
b = a Mod b
a = t
End While
If WholeNumber = 0 Then
GetFraction = CStr(Numerator / a) & "/" & CStr(Denomenator / a)
Else
GetFraction = CStr(WholeNumber) & " " & CStr(Numerator / a) & "/" & CStr(Denomenator / a)
End If
End If
End If
End Function
If you mean you'd like to round the decimal received by the function before the value is converted, you could add the built in Round function where ever Num is referenced. The following can be used to transform the values -- the first parameter is the value you wish to round and the second specifies how many digits after the decimal point.
Decimal.Round(value,numbersRightOfDecimalPoint)
Since the values are Double datatypes, you will likely have to convert them to decimals with a ToDecimal function. The ToDecimal function takes the value to convert and a regional culture, which we can just set to Nothing so it'll just round as normal.
Convert.ToDecimal(value, culture)
From what I can see, you should only need to modify these two lines where Num is referenced to round the value throughout the function.
WholeNumber = Fix(Decimal.Round(Convert.ToDecimal(Num,Nothing), 2))
DecimalNumber = Decimal.Round(Convert.ToDecimal(Num,Nothing),2) - Fix(Decimal.Round(Convert.ToDecimal(Num,Nothing),2))
Which yields a result like this:
.501324532 >> 1/2
EDIT: On looking at your question again, it seems you MIGHT want to convert the decimals into fractions relating to measurements such as feet and inches. For that, refer to this link which has additional functions you can implement for that requirement.
Related
I am borrowing some code from here but I have no idea how to get the code to not run infinitely.
Specifically, what I don't know how to do is to reference previously yielded digits and check that if the currently yielded digit has been returned. I want the function to stop once it starts looping. Is there a way to reference previously yielded values?
Here's a non generator solution
#when doing long division on a pair of numbers, (a,b), when you proceed through the algorigthm,
#you get new pairs (rem,b). You stop the algorithm when rem==0 or when the remainder is present
#in the existing list of digits
def decimals(number):
dividend = 1
digit = []
while dividend:
if dividend//10 in digit:
return digit
digit += [dividend // number]
dividend = dividend % number * 10
a more streamlined version, again still not generator, would be
def decimals(number):
dividend = 1
digit = []
while dividend and dividend//10 not in digit:
digit += [dividend // number]
dividend = dividend % number * 10
return digit
So for a homework assignment we had to make a program that converted a number from one base to another (i.e. 110 in base 2 to 6 in base 10). I asked my friend how he did his because I was having trouble and he just sent me his code and nothing else. Can someone explain the logic of this code so that I can make my own program and actually understand how to do this problem. Thanks!
import java.util.*;
public class Base_Converter {
public static final String value = "0123456789ABCDEFGHIJKLMNOPQRSTUVWXYZ";
public static void main(String args[]){
int x, y;
String num, base10 = "";
Scanner scan = new Scanner(System.in);
System.out.println("Enter a number you want to convert.");
num = scan.nextLine();
num = num.toUpperCase();
System.out.println("What base is it in?");
x = scan.nextInt();
System.out.println("What base do you want to convert it to?");
y = scan.nextInt();
if(x <= 36 && y <= 36 && x > 1 && y > 1){
base10 = toBase10(num,x);
num = newBase(base10,y);
System.out.println(num);
}
}
public static String toBase10(String num, int from){
long total = 0;
int counter = num.length();
char[] stringArray = num.toCharArray();
for(char w : stringArray){
counter--;
total += value.indexOf(w)*Math.pow(from,counter);
}
return String.valueOf(total);
}
public static String newBase(String num, int to){
String total = "";
int current = 0;
while(Integer.valueOf(num) > 0){
current = Integer.valueOf(num)%to;
total = value.charAt(current)+total;
num = String.valueOf(Integer.valueOf(num)/to);
}
return total;
}
}
I think you should be focusing not on what your friend's code does, but instead with how to do the assignment yourself, because I think your problems lie with a lack of understanding on your part. Instead of leaving you high and dry though I'll walk you through some of the specifics of base-conversion.
First, read user input. It looks like you're using Java, so just use a scanner to do this. At minimum you'll want to read the number you're converting, what base it is in, and what base the output will be in.
Next, we want to convert the number. You could directly convert numbers to each other (i.e. converting base 2 to base 8) but that requires more brainpower than I am willing to offer right now. Instead, I would suggest always first converting the user-inputted number to base 10 (much like your friend did). So how do we convert a number of an unknown base to base 10?
So let's break down how a number is represented: lets say we have the number 234 in base ten. This is equivalent to 4*10^0 + 3*10^1 + 2*10^2 or 4 + 30 + 200 = 234. You can use this same conversion for any other numbers. I.E. if the number is 1763 in base 8, the value in base 10 will be 3*8^0 + 6*8^1 + 7*8^2 + 1*8^3 or 3 + 48 + 448 + 512 = 1011 base 10(try entering 1763 here for proof. So to convert to decimal, you just need to see to multiply each individual number time your base to the power of its place minus 1. For example, since 1 is the fourth number in the 1763 you multiply it times 8^(4-1). Since, you are reading a string from the user. You'll need to convert each character of the string to an integer using the ascii chart.
Now to convert from base ten to anything. Instead of multiplying, you just divide each value and write the remainder! I'll let someone else describe this procedure.
Now just store this new value as a string doing somethings like
String output = "";
output += newValue;
In computer science, just copying someone else's code is way more harmful than helpful. Hope this helps!
This question already has answers here:
Compare double in VBA precision problem
(10 answers)
Closed 8 years ago.
I guess it has something to do with the precision but I don't understand it. I have this piece of code that should perform rounding to 2 places (value is the input):
Dim a As Double
Dim b As Double
Dim c As Double
Dim result As Double
a = CDbl(value) * 100
b = a + 0.5 //because Int in the next line performs floor operation, 0.5 is added to ensure proper rounding, example for 123.5: Int(123.5) = 123 but we need Int(123.5 + 0.5) = 124
c = Int(b)
result = c / 100
The thing is, it doesn't work properly for a value 134.605. While debugging I found out that a value is calculated incorrectly.
In fact I have checked this:
?13460.5 = (134.605*100)
False
?(134.605*100) - 13460.5
-1,02318153949454E-12
And I'm stuck. I can either rewrite the rounding function differently, but I don't have an idea for it without *100 multiplication. Or I could find out how to make *100 operation work correctly for all the values. Could anyone try to explain me why it happens and suggest a solution?
Try Decimal data type. Although you cannot explicitly declare a variable of this type, you can convert it to such implicitly by declaring it as Variant and converting using CDec.
Debug.Print 13460.5 = CDec(134.605 * 100) 'Output - True
New VBA user here, engineer-not a programmer. Your patience is appreciated. Did spend hours in help and online trying to find this answer. Found some answers to this, but they were for php. Working with MS Office Home and Student 2007.
I have a list of 8 equations. I have the user input the number of the equation they want to evaluate, I call that number index. Is there a way to put the index into a function name when it's defined?
such as:
Function PlotFun[index]= some f(x)
Or is it possible to redefine the function using an index within a subroutine?
such as:
If index=1 then PlotFun=PlotFun[index] 'so PlotFun would equal PlotFun1
I think I read in the help that a function has to be defined in a function routine, so this one probably isn't feasible.
Or is it possible to read the function from a cell in excel? I tried using
Function PlotFun=Worksheets(1).Range("BC6")
where BC6 contains "24 - 50 * x + 35 * x ^ 2 - 10 * x ^ 3 + x * 4" which is correct syntax for a function of x, as it was copied from my PlotFun1 routine. But I don't have the syntax down right. I get Compile Error: Expected: End of statement, right at the equals sign.
I've also been referred to the lamda function, but again, I get the Expected: End of Statement error.
Sub Bisection()
Dim index
Call FuncIndex 'sets the index number for which equation to use for analysis
If index = 1 Then
Dim PlotFun=Function(x) x ^ 3 - 6 * x ^ 2 + 11 * x - 6
If index = 2 Then
Dim PlotFun=Function(x) 24 - 50 * x + 35 * x ^ 2 - 10 * x ^ 3 + x * 4
Do 'my calculations using PlotFun
Loop 'for specified error or iterations
End Sub
I need to use PlotFun or PlotFun1 in a few places within many subroutines. I don't want to have to write/copy code for each f(x). Perhaps there is a better way to do this than what I've thought of? I cannot use an array, as the equations are not all polynomials.
Thank you!
Is there a way to put the index into a function name when it's
defined? such as:
Not in-line really. You can use a select case switch, or a series of if/else statements. I ordinarily prefer the select case method.
NOTE This code does not specify any value for x, so it will be interpreted as an Empty or zero-value, unless you change the code or provide a means for user to input the variable x value.
Sub WhichFunction()
Dim i as Long
Dim functionResult as Double
i = Application.InputBox "Please enter the function's index #"
Select Case i
Case 1
functionResult = x ^ 3 - 6 * x ^ 2 + 11 * x - 6
Case 2
functionResult = - 50 * x + 35 * x ^ 2 - 10 * x ^ 3 + x * 4
Case 3
'etc.
Case 4
Case 5
Case 6
Case 7
Case 8
Case else
MsgBox "invalid function index!"
End Select
MsgBox functionResult
End Sub
About your code:
I get the Expected: End of Statement error
Probably because your Dim statements don't end where they should. In VBA, you generally can't declare and simultaneously assign a variable. There are exceptions, and visual shortcuts, but that's not necessary to discuss here.
Or is it possible to read the function from a cell in excel? I tried
using Function PlotFun=Worksheets(1).Range("BC6")
Yes, it is possible for a function to read from a specific cell, but not the way you're implementing it. YOu need to go back to basics and learn how to create a function, e.g,:
Function MyFunctionName(arg1 as integer, arg2 as integer)
'Code the evaluates some methods on the arguments provided
Dim myVal as Double
myVal = arg1 ^ arg2
MyFunction = myVal 'Return the calculated value
End Function
Likewise you could do:
Function GetValueFromSheet(byVal cl as Range)
'This function will ALWAYS return the value in B6
GetValueFromSheet = Range("B6").Value
End Function
It sounds like you want to vary what algorithm is used, or in your case what equation is called based on a parameter that you would pass to a single function. This problem can be solved by the use a of a well know software pattern known as the "strategy pattern". This pattern allows you to vary an algorithm while keeping its implementation the same.
You can combine the strategy pattern with a factory pattern to achieve the desired architecture you are seeking.
Here is a fairly clear vba implementation of a strategy pattern.
Hope this helps.
VBA is the worst language to try to do this in. (Actually, it's the worst language to try to do most things in.)
VBA functions are unfortunately not values or objects, and they cannot be stored in variables whatsoever. Therefore, none of this is remotely legal:
Function PlotFun[index]= some f(x)
Function PlotFun=Worksheets(1).Range("BC6")
Dim PlotFun=Function(x) x ^ 3 - 6 * x ^ 2 + 11 * x - 6
Since you don't need too many functions, the easiest solution is this:
Function PlotFun(index, x)
Select Case index
Case 1
PlotFun = x ^ 3 - 6 * x ^ 2 + 11 * x - 6
Case 2
PlotFun = 24 - 50 * x + 35 * x ^ 2 - 10 * x ^ 3 + x * 4
Case 3
' ... and so on
End Select
End Function
I.e., declare PlotFun as an ordinary function, and use your index variable to tell it what internal expression to evaluate. The disadvantage is that you will have to include the function index variable everywhere you want to call PlotFun.
Note that the PlotFun = ... syntax here does not assign the function itself, but rather is VBA's way of setting the return value from a particular invocation of the function. Within the function, PlotFun is just the name of a variable to assign to.
This isn't necessarily a programming question but i'm sure you folks know how to do it. How would i convert floating point numbers into binary.
The number i am looking at is 27.625.
27 would be 11011, but what do i do with the .625?
On paper, a good algorithm to convert the fractional part of a decimal number is the "repeated multiplication by 2" algorithm (see details at http://www.exploringbinary.com/base-conversion-in-php-using-bcmath/, under the heading "dec2bin_f()"). For example, 0.8125 converts to binary as follows:
1. 0.8125 * 2 = 1.625
2. 0.625 * 2 = 1.25
3. 0.25 * 2 = 0.5
4. 0.5 * 2 = 1.0
The integer parts are stripped off and saved at each step, forming the binary result: 0.1101.
If you want a tool to do these kinds of conversions automatically, see my decimal/binary converter.
Assuming you are not thinking about inside a PC, just thinking about binary vs decimal as physically represented on a piece of paper:
You know .1 in binary should be .5 in decimal, so the .1's place is worth .5 (1/2)
the .01 is worth .25 (1/4) (half of the previous one)
the .001 is worth (1/8) (Half of 1/4)
Notice how the denominator is progressing just like the whole numbers to the left of the decimal do--standard ^2 pattern? The next should be 1/16...
So you start with your .625, is it higher than .5? Yes, so set the first bit and subtract the .5
.1 binary with a decimal remainder of .125
Now you have the next spot, it's worth .25dec, is that less than your current remainder of .125? No, so you don't have enough decimal "Money" to buy that second spot, it has to be a 0
.10 binary, still .125 remainder.
Now go to the third position, etc. (Hint: I don't think there will be too much etc.)
There are several different ways to encode a non-integral number in binary. By far the most common type are floating point representations, especially the one codified in IEEE 754.
the code works for me is as below , you can use this code to convert any type of dobule values:
private static String doubleToBinaryString( double n ) {
String val = Integer.toBinaryString((int)n)+"."; // Setting up string for result
String newN ="0" + (""+n).substring((""+n).indexOf("."));
n = Double.parseDouble(newN);
while ( n > 0 ) { // While the fraction is greater than zero (not equal or less than zero)
double r = n * 2; // Multiply current fraction (n) by 2
if( r >= 1 ) { // If the ones-place digit >= 1
val += "1"; // Concat a "1" to the end of the result string (val)
n = r - 1; // Remove the 1 from the current fraction (n)
}else{ // If the ones-place digit == 0
val += "0"; // Concat a "0" to the end of the result string (val)
n = r; // Set the current fraction (n) to the new fraction
}
}
return val; // return the string result with all appended binary values
}