Float Variable Constantly Evaluating to 0 [duplicate] - variables

This question already has answers here:
Why does division result in zero instead of a decimal?
(5 answers)
Closed 7 months ago.
I am in a C++ class and for my final I am developing a program that asks a user whether they want to convert Fahrenheit temps to Celsius or Kelvin (there is a third menu option, but it is irrelevant to the issue). One of the tasks is to write a void function to convert to Celsius and to convert to Kelvin. I am also supposed to store the Celsius conversion, the Kelvin conversion, and the Fahrenheit number in an array. I am running into an issue where my floating-point Celsius variable (cel in the program) is always 0. This results in Kelvin always being 273.15. I have checked and "f" is storing the number that I input. Below is my function:
// Celcius function
void showCelcius(float f)
{
float cel, kel;
cel = (5/9) * (f - 32);
cout << cel << endl; // Test to check cel value after equation
kel = cel + 273.15;
cout << fixed << showpoint << setprecision(1);
cout << f << " Fahrenheit = "
<< cel << " Celcius\n";
temps[totalCount][0] = f;
temps[totalCount][1] = cel;
temps[totalCount][2] = kel;
}
Here is the ouput:
I have also tried putting the whole equation in parentheses. How can I get the variable "cel" to evaluate to the result of the equation?

I figured it out. It appears that since '5' and '9' were of type int it was not evaluating the equation at all. I added static_cast() to each number and it works.
// Celcius function
void showCelcius(float f)
{
float cel, kel;
cel = (static_cast<float>(5)/static_cast<float>(9))*(f - static_cast<float>(32));
cout << cel << endl;
kel = cel + 273.15;
cout << fixed << showpoint << setprecision(1);
cout << f << " Fahrenheit = "
<< cel << " Celcius\n";
temps[totalCount][0] = f;
temps[totalCount][1] = cel;
temps[totalCount][2] = kel;
}

Related

Testing Bits in VBA

Is it OK to test bits in VBA in the manner shown below, or does it have some hidden gotchas ?
Dim x As Byte
x = FooFn(42)
If (x And &H80) Then Debug.Print "The MSB is set"
or must I test it like this:
Dim x As Byte
x = FooFn(42)
If (x And &H80) <> 0 Then Debug.Print "The MSB is set"
On the other hand, what is the optimal way to test whether this bit is clear (not set) ?
Is this the best I can do:
Dim x As Byte
x = FooFn(43)
If (x And &H80) = 0 Then Debug.Print "The MSB is not set"
Also, what is this the minimum amount of parentheses I can get away with ?

Properly formatting a text table in Visual Basic

Currently I'm trying to write a program in Visual Basic to output a text based table based on a set amount of results.
I'm trying to incorporate something like the below C++ code to properly format the table but can't figure out what code to use in Visual Basic to achieve a similar effect. (I know that cout and endl are particular to C++ but I'm hoping that there exists an alternative for VB)
cout << endl << "Month# Interest Amount Monthly Amount New Amount" << endl;
int counter = 1;
while (counter <= length * 12) {
cout << right << setw(6) << counter; // Month Counter
}
Without giving too much of the code and making this a mess, this is what I have.
Dim strOutput As String
Dim strParticipantList As String = ""
Dim outFile As IO.StreamWriter
strOutput = Trim(eventName & " Final Results") & vbNewLine + vbNewLine + _
"Total Number of Participants: " + TotalParticipants & vbNewLine
For Each storage As StopwatchStorage In _storage
strParticipantList &= storage.ParticipantOrder.Text
Next
The idea is that I will loop through each item in storage and properly format the row as a string formatted like the cout stated from the C++ code.
Using outFile As New IO.StreamWriter("File Path Here")
outFile.WriteLine("{0} Final Results", eventName)
outFile.WriteLine()
outFile.WriteLine("Total Number of Participants: {0}", TotalParticipants)
outFile.WriteLine()
'Using C++ example with some made-up variable names to show how this can work
outFile.WriteLine("Month# Interest Amount Monthly Amount New Amount")
For Each storage As StopwatchStorage In _storage
outFile.WriteLine("{0,-6} {1,-20} {2,-18} {3,-14}", _
storage.Month, storage.Interest, storage.MonthlyTotal, storage.NewTotal)
Next
End Using
The {x} placeholders mark indices in the later parameters for substitution. An {m,n} placeholder uses the portion after the comma to set the width of the item. A positive number is left-aligned for that many characters, a negative number is right-aligned. Here's the documentation for how it works.

How do I split a 16-bit value into two 8-bit values in VB.NET?

I have a 16-bit value like this:
0000000000000011
I want to split this in two 8-bit values like:
00000000 and 00000011
The 16-bit value is a variable, byte_val1, which is a unsigned 16-bit integer.
How can I do this in VB.NET?
You can use the BitConverter class:
Dim bytes As Byte() = BitConverter.GetBytes(byte_val1)
Now bytes(0) contains the lower byte (00000011) and bytes(1) contains the higher byte (00000000).
To obtain lower 8 bits, you need to and it with 11111111, or 0xff
To obtain upper 8 bits, you need to and it with 1111111100000000, or 0xff00
Then to an arithmetic left shift exactly 8 bits.
I have not done Visual Basic in a while, but the idea is as follows:
word a = 1930392;
byte alower = a & 0xff;
byte ahigher = (a & 0xff00) >> 8;
Oh, here's a code I made with three textboxes named a, alower, aupper and a button btnDoIt:
Private Sub btnDoIt_Click(sender As Object, e As EventArgs) Handles btnDoIt.Click
Dim localA = Integer.Parse(a.Text())
Dim localALower = localA And &HFF
Dim localAUpper = (localA And &HFF00) >> 8
alower.Text = localALower
aupper.Text = localAUpper
End Sub
Sidenote: (localA And &HFF00) >> 8 is equivelent to (localA >> 8) And &HFF
A simple bitshift should work if you want certain byte(s) from any value (32 bit, 64 bit, 128 bit, etc..).
The simplest way is to AND ("binary AND", also written as "&") the source with the bits you want and then to shift it as many times as needed to get the desired value.
Dim initial as Integer = &H123456 ' Hex: 0x123456
Dim result as Byte = (initial AND &H00FF00) >> 8
'result = 0x34
and if you would like to join them again it's even simpler:
Dim initial as Integer = &H123456 ' Hex: 0x123456
Dim result_a as Byte = (initial AND &H00FF00) >> 8
Dim result_b as Byte = (initial AND &HFF0000) >> 16
Dim final as Integer = (result_a << 8) or (result_b << 16)
'final = 0x123400

Reading MP3 Frameheader - assigning bit values to variables

I am learning visual basic .net and I am attempting to translate some java source code to a vb.net project. The project reads mp3 details and then splits the file accurately according to the frameheader details etc.
My question relates to reading the frame header of mp3 files. I understand that the frame details are contained in the first 4 (32-bits) bytes of a frame and certain bits represent certain values as detailed here: http://www.mp3-tech.org/programmer/frame_header.html
Using FileStream I have been able to read this data and display it in binary within a text box.
I am looking for help on reading the bits and assigning them to variables within my class. I am not sure what would be the correct procedure to do this as some values as 1, 2 or 4 bits in length e.g. bits 19-20 = MpegType, bits 12-15 = BitrateIndex, bit 9 = Padding etc.
I have looked at similar projects available on codeproject.com but I do not understand how they have achieved the above.
Any help is much appreciated.
EDIT:
Here is the main sub so far, I have not included the code declaring variables and properties etc.
Public Sub decode()
Dim fs As FileStream
Dim bytes(3) As Byte
fs = New FileStream(mFilename, FileMode.Open, FileAccess.Read)
If fs.CanRead Then
fs.Read(bytes, 0, bytes.Length)
For i As Integer = 0 To bytes.Length - 1
Form1.RichTextBox.Text += Convert.ToString(bytes(i), 2).PadLeft(8, "0"c) & vbCrLf
Next
fs.Close()
fs.Dispose()
Else
MsgBox("File CANNOT be read!!!")
End If
End Sub
When this is run the output in the rich text box is as follows:
11111111
11111010
10110011
01001100
I want to read through these bits and assign the appropriate values to the variables e.g.
Read the first 12 bits for sync value.
Read bit 13 for mpegID value.
Read bit 14 and 15 for layerID value etc.
Hope that is clearer.
The java code is as follows:
public FrameHeader() {
this.header32 = 0;
valid = false;
}
public FrameHeader(int header32) {
this.header32 = header32;
decode();
}
public void setHeader32(int header32) {
this.header32 = header32;
decode();
}
private void decode() {
mpegID = (header32 >> 19) & 3;
layerID = (header32 >> 17) & 3;
crc16used = (header32 & 0x00010000) == 0;
bitrateIndex = (header32 >> 12) & 0xF;
samplingrateIndex = (header32 >> 10) & 3;
padding = (header32 & 0x00000200) != 0;
privateBitSet = (header32 & 0x00000100) != 0;
mode = (header32 >> 6) & 3;
modeExtension = (header32 >> 4) & 3;
copyrighted = (header32 & 0x00000008) != 0;
original = (header32 & 0x00000004) == 0; // bit set -> copy
emphasis = header32 & 3;
valid = (mpegID != ILLEGAL_MPEG_ID) && (layerID != ILLEGAL_LAYER_ID) && (bitrateIndex != 0)
&& (bitrateIndex != 15) && (samplingrateIndex != ILLEGAL_SR);
if (valid) {
samplingrateHz = SAMPLING_RATES[samplingrateIndex];
if (mpegID == MPEG2_ID)
samplingrateHz >>= 1; // 16,22,48 kHz
if (mpegID == MPEG25_ID)
samplingrateHz >>= 2; // 8,11,24 kHz
channels = (mode == MODE_MONO) ? 1 : 2;
bitrateKBPS = BITRATE_MAP[mpegID][layerID][bitrateIndex];
if (layerID == LAYER1_ID) {
// layer 1: always 384 samples/frame and 4byte-slots
samplesPerFrame = 384;
bytesPerSlot = 4;
}
else {
// layer 2: always 1152 samples/frame
// layer 3: MPEG1: 1152 samples/frame, MPEG2/2.5: 576
// samples/frame
samplesPerFrame = ((mpegID == MPEG1_ID) || (layerID == LAYER2_ID)) ? 1152 : 576;
bytesPerSlot = 1;
}
frameSize = ((bitrateKBPS * 125) * samplesPerFrame) / samplingrateHz;
if (bytesPerSlot > 1)
frameSize -= frameSize % bytesPerSlot;
if (padding)
frameSize += bytesPerSlot;
}
}
Here is a detailed explanation of frames and a formula on how data is held in the header, the first 4 bytes of a frame.
I am not sure what you are trying to accomplish but, just in case, here you go. There is no point in reinventing the wheel.
.Net has class called BitArray that you would use to store your bits.
I have come across a similar project that uses a function to converts bits to string. I've combined this code with another example I found that changed a binary string to integer. Interested to hear of alternative methods?
Public Function BinaryToInteger(ByVal objBitArray As BitArray, ByVal intStart As Integer, ByVal intEnd As Integer) As Integer
Dim BinaryString As String
Dim BinaryNum As Integer
Dim BitCount As Short
BinaryString = ""
For i As Integer = intStart To intEnd
BinaryString &= IIf(objBitArray.Item(i), "1", "0")
Next
For BitCount = 1 To Len(BinaryString)
BinaryNum = BinaryNum + (CDbl(Mid(BinaryString, Len(BinaryString) - BitCount + 1, 1)) * (2 ^ (BitCount - 1)))
Next BitCount
BinaryToInteger = BinaryNum
End Function

Converting JScript to VB.NET - Questions

I'm trying to convert some functions written in JScript to VB.NET (I'm porting a classic ASP page to ASP.NET) and having issues as I'm not very familiar with JScript. I'm having issues with converting even the function declaration properly in VB.NET. In my converted code VS2008 is giving me an error saying "Array bounds can not be specified in type identifiers". I don't know how to modify my function declaration to return an Array but ALSO accept an array as input as the JScript declaration does. Any ideas? Am I approaching this wrong?
Thanks in advance.
Here is one of the original JScript functions:
function binl2byt(binarray)
{
var hex_tab = "0123456789abcdef";
var bytarray = new Array(binarray.length * 4);
var str = "";
for(var i = 0; i < binarray.length * 4; i++)
{
bytarray[i] = (binarray[i>>2] >> ((i%4)*8+4) & 0xF) << 4 | binarray[i>>2] >> ((i%4)*8) & 0xF;
}
return bytarray;
}
Here is what I have in VB.NET so far:
Public Function binl2byt() As Array(byval binarray as array)
Dim hex_tab As String = "0123456789abcdef"
Dim bytarray() As Byte
Dim str As String = ""
For I As Integer = 0 To (bytarray.Length * 4) Step 1
bytarray(I) = ((binarray(I >> 2) >> ((I Mod (4)) * 8 + 4) & Oxf) << 4) Or (binarray(I >> 2) >> ((I Mod (4) * 8) & OxF))
Next
Return bytarray
End Function
There is no need for this function, it is already there in .NET for you.
BitConverter.ToString(Bytes);
Where Bytes is your byte array.