Skip to main content
added 1 character in body
Source Link

Apple's System Management Controller uses FPE2 and SP78 as floating-point formats.

While writing a Java library that that interfaces with the SMC, I ported someone's C function to convert read a FPE2-formatted byte array as a float.

public static float strtof(byte[] bytes, int size, int e) {
    int total = 0;
    // Add up bits to left of fractional bits
    for (int i = 0; i < size; i++) {
        if (i == (size - 1))
            total += (bytes[i] & 0xff) >> e;
        else
            total += (bytes[i] & 0xff) << (size - 1 - i) * (8 - e);
    }
    // Mask fractional bits and divide
    return total + (bytes[size - 1] & (1 << e) - 1) / (float) (1 << e);
}

The bytes and size parameters come from reading a structure in Apple's SMC interface. The array is a byte[32] value in a structure, where a second part of the structure states how many of the elements of the array are significant. In the use case, getting fan speed, bytes[0] and bytes[1] will be populated with data (the other 30 bytes are ignored) and size will have a value of 2.

In the given code, the value of e represents how many rightmost bits out of the size bytes are for the fractional part. If e is 2 (such as for FPE2), then the final 2 bits can have values 0, 1, 2, or 3 representing the fractions 0.0, 0.25, 0.5, and 0.75. The remaining leading bits are interpreted as the integer part.

Example input:

  • bytes = { 0x00, 0x05, 0x00, 0x00, ... } // First 2 bitsbytes binary 101
  • size = 2
  • e = 2

Example output: 1.25 // Integer portion is 1, fraction is 1/4.


Did I do it right (assuming arguments are already validated: e will never be more than 8, and size will never be more than 4)? Points of concern are order of operation, what happens bitwise when I promote a byte to an int and then shift it.

While this function converts an FPE2 format number, I'm trying to make it a bit more general. A similar format, SP78, is used for temperature. The rightmost 8 bits (divided by 256) are the fractional portion, the left 8 bits are a signed byte. (This method is not intended to handle the signed calculation but this is given as a reference.)

Apple's System Management Controller uses FPE2 and SP78 as floating-point formats.

While writing a Java library that that interfaces with the SMC, I ported someone's C function to convert read a FPE2-formatted byte array as a float.

public static float strtof(byte[] bytes, int size, int e) {
    int total = 0;
    // Add up bits to left of fractional bits
    for (int i = 0; i < size; i++) {
        if (i == (size - 1))
            total += (bytes[i] & 0xff) >> e;
        else
            total += (bytes[i] & 0xff) << (size - 1 - i) * (8 - e);
    }
    // Mask fractional bits and divide
    return total + (bytes[size - 1] & (1 << e) - 1) / (float) (1 << e);
}

The bytes and size parameters come from reading a structure in Apple's SMC interface. The array is a byte[32] value in a structure, where a second part of the structure states how many of the elements of the array are significant. In the use case, getting fan speed, bytes[0] and bytes[1] will be populated with data (the other 30 bytes are ignored) and size will have a value of 2.

In the given code, the value of e represents how many rightmost bits out of the size bytes are for the fractional part. If e is 2 (such as for FPE2), then the final 2 bits can have values 0, 1, 2, or 3 representing the fractions 0.0, 0.25, 0.5, and 0.75. The remaining leading bits are interpreted as the integer part.

Example input:

  • bytes = { 0x00, 0x05, 0x00, 0x00, ... } // First 2 bits binary 101
  • size = 2
  • e = 2

Example output: 1.25 // Integer portion is 1, fraction is 1/4.


Did I do it right (assuming arguments are already validated: e will never be more than 8, and size will never be more than 4)? Points of concern are order of operation, what happens bitwise when I promote a byte to an int and then shift it.

While this function converts an FPE2 format number, I'm trying to make it a bit more general. A similar format, SP78, is used for temperature. The rightmost 8 bits (divided by 256) are the fractional portion, the left 8 bits are a signed byte. (This method is not intended to handle the signed calculation but this is given as a reference.)

Apple's System Management Controller uses FPE2 and SP78 as floating-point formats.

While writing a Java library that that interfaces with the SMC, I ported someone's C function to convert read a FPE2-formatted byte array as a float.

public static float strtof(byte[] bytes, int size, int e) {
    int total = 0;
    // Add up bits to left of fractional bits
    for (int i = 0; i < size; i++) {
        if (i == (size - 1))
            total += (bytes[i] & 0xff) >> e;
        else
            total += (bytes[i] & 0xff) << (size - 1 - i) * (8 - e);
    }
    // Mask fractional bits and divide
    return total + (bytes[size - 1] & (1 << e) - 1) / (float) (1 << e);
}

The bytes and size parameters come from reading a structure in Apple's SMC interface. The array is a byte[32] value in a structure, where a second part of the structure states how many of the elements of the array are significant. In the use case, getting fan speed, bytes[0] and bytes[1] will be populated with data (the other 30 bytes are ignored) and size will have a value of 2.

In the given code, the value of e represents how many rightmost bits out of the size bytes are for the fractional part. If e is 2 (such as for FPE2), then the final 2 bits can have values 0, 1, 2, or 3 representing the fractions 0.0, 0.25, 0.5, and 0.75. The remaining leading bits are interpreted as the integer part.

Example input:

  • bytes = { 0x00, 0x05, 0x00, 0x00, ... } // First 2 bytes binary 101
  • size = 2
  • e = 2

Example output: 1.25 // Integer portion is 1, fraction is 1/4.


Did I do it right (assuming arguments are already validated: e will never be more than 8, and size will never be more than 4)? Points of concern are order of operation, what happens bitwise when I promote a byte to an int and then shift it.

While this function converts an FPE2 format number, I'm trying to make it a bit more general. A similar format, SP78, is used for temperature. The rightmost 8 bits (divided by 256) are the fractional portion, the left 8 bits are a signed byte. (This method is not intended to handle the signed calculation but this is given as a reference.)

Link to updated final code
Source Link

Apple's System Management Controller uses FPE2 and SP78 as floating-point formats.

While writing a Java library that that interfaces with the SMCinterfaces with the SMC, I portedported someone's C function to convert read a FPE2-formatted byte array as a float.

public static float strtof(byte[] bytes, int size, int e) {
    int total = 0;
    // Add up bits to left of fractional bits
    for (int i = 0; i < size; i++) {
        if (i == (size - 1))
            total += (bytes[i] & 0xff) >> e;
        else
            total += (bytes[i] & 0xff) << (size - 1 - i) * (8 - e);
    }
    // Mask fractional bits and divide
    return total + (bytes[size - 1] & (1 << e) - 1) / (float) (1 << e);
}

The bytes and size parameters come from reading a structure in Apple's SMC interface. The array is a byte[32] value in a structure, where a second part of the structure states how many of the elements of the array are significant. In the use case, getting fan speed, bytes[0] and bytes[1] will be populated with data (the other 30 bytes are ignored) and size will have a value of 2.

In FPE2the given code, the value of e represents how many rightmost bits out of the size bytes are for the fractional part. If e is 2 (such as for FPE2), then the final 2 bits can have values 0, 1, 2, or 3 representing the fractions 0.0, 0.25, 0.5, and 0.75. The remaining leading bits are interpreted as the integer part.

Example input:

  • bytes = { 0x00, 0x05, 0x00, 0x00, ... } // BinaryFirst 2 bits binary 101
  • size = 2
  • e = 2

Example output: 1.25 // Integer portion is 1, fraction is 1/4.


Did I do it right (assuming arguments are already validated: e will never be more than 8, and size will never be more than 4)? Points of concern are order of operation, what happens bitwise when I promote a byte to an int and then shift it.

While this function converts an FPE2 format number, I'm trying to make it a bit more general. A similar format, SP78, is used for temperature. The rightmost 8 bits (divided by 256) are the fractional portion, the left 8 bits are a signed byte. (This method is not intended to handle the signed calculation but this is given as a reference.)

Apple's System Management Controller uses FPE2 and SP78 as floating-point formats.

While writing a Java library that that interfaces with the SMC, I ported someone's C function to convert read a FPE2-formatted byte array as a float.

public static float strtof(byte[] bytes, int size, int e) {
    int total = 0;
    // Add up bits to left of fractional bits
    for (int i = 0; i < size; i++) {
        if (i == (size - 1))
            total += (bytes[i] & 0xff) >> e;
        else
            total += (bytes[i] & 0xff) << (size - 1 - i) * (8 - e);
    }
    // Mask fractional bits and divide
    return total + (bytes[size - 1] & (1 << e) - 1) / (float) (1 << e);
}

The bytes and size parameters come from Apple's SMC interface. The array is a byte[32] value in a structure, where a second part of the structure states how many of the elements of the array are significant. In the use case, getting fan speed, bytes[0] and bytes[1] will be populated with data and size will have a value of 2.

In FPE2, the value of e represents how many rightmost bits out of the size bytes are for the fractional part. If e is 2, then the final 2 bits can have values 0, 1, 2, or 3 representing the fractions 0.0, 0.25, 0.5, and 0.75. The remaining leading bits are interpreted as the integer part.

Example input:

  • bytes = { 0x00, 0x05 } // Binary 101
  • size = 2
  • e = 2

Example output: 1.25 // Integer portion is 1, fraction is 1/4.


Did I do it right (assuming arguments are already validated: e will never be more than 8, and size will never be more than 4)? Points of concern are order of operation, what happens bitwise when I promote a byte to an int and then shift it.

While this function converts an FPE2 format number, I'm trying to make it a bit more general. A similar format, SP78, is used for temperature. The rightmost 8 bits (divided by 256) are the fractional portion, the left 8 bits are a signed byte. (This method is not intended to handle the signed calculation but this is given as a reference.)

Apple's System Management Controller uses FPE2 and SP78 as floating-point formats.

While writing a Java library that that interfaces with the SMC, I ported someone's C function to convert read a FPE2-formatted byte array as a float.

public static float strtof(byte[] bytes, int size, int e) {
    int total = 0;
    // Add up bits to left of fractional bits
    for (int i = 0; i < size; i++) {
        if (i == (size - 1))
            total += (bytes[i] & 0xff) >> e;
        else
            total += (bytes[i] & 0xff) << (size - 1 - i) * (8 - e);
    }
    // Mask fractional bits and divide
    return total + (bytes[size - 1] & (1 << e) - 1) / (float) (1 << e);
}

The bytes and size parameters come from reading a structure in Apple's SMC interface. The array is a byte[32] value in a structure, where a second part of the structure states how many of the elements of the array are significant. In the use case, getting fan speed, bytes[0] and bytes[1] will be populated with data (the other 30 bytes are ignored) and size will have a value of 2.

In the given code, the value of e represents how many rightmost bits out of the size bytes are for the fractional part. If e is 2 (such as for FPE2), then the final 2 bits can have values 0, 1, 2, or 3 representing the fractions 0.0, 0.25, 0.5, and 0.75. The remaining leading bits are interpreted as the integer part.

Example input:

  • bytes = { 0x00, 0x05, 0x00, 0x00, ... } // First 2 bits binary 101
  • size = 2
  • e = 2

Example output: 1.25 // Integer portion is 1, fraction is 1/4.


Did I do it right (assuming arguments are already validated: e will never be more than 8, and size will never be more than 4)? Points of concern are order of operation, what happens bitwise when I promote a byte to an int and then shift it.

While this function converts an FPE2 format number, I'm trying to make it a bit more general. A similar format, SP78, is used for temperature. The rightmost 8 bits (divided by 256) are the fractional portion, the left 8 bits are a signed byte. (This method is not intended to handle the signed calculation but this is given as a reference.)

deleted 544 characters in body; edited tags
Source Link
200_success
  • 145.7k
  • 22
  • 191
  • 481

I'm writing a method in Java that converts a byte array to a float. While my specific use case is converting an FPE2 format number, I'm trying to make it a bit more generalApple's System Management Controller uses FPE2 and SP78 as floating-point formats.

In FPE2, the leftmost E (14) bits are converted to the integer portion ofWhile writing a Java library that that interfaces with the numberSMC, and the rightmost 2 digits represent the floating point portion

Below is my attempt. Did I do it right (assuming I've checked arguments for validity: byte.length<=size<=4, e<=8)? Points of concern are order of operation, what happens bitwise when I promoteported someone's C function to convert read a FPE2-formatted byte to an int and then shift it.

Example input:

  • bytes = { 0x00, 0x05 } // Binary 101
  • size = 2
  • e = 2

Example output: 1.25array as a // Integer portion is 1, fraction is 1/4float.

Edit #1 to add clarification:

The arraybytes and size values are return valuessize parameters come from another API, Apple's SMC interface. The array is a byte[32] value in a structure, where a second part of the structure states how many of the elements of the array are significant. In the use case, getting fan speed, bytes[0] and bytes[1] will be populated with data and size will have a value of 2.

TheIn FPE2, the value of ee represents how many bits are for floating points. For FPE2 the two bytes (size=2) have 14 bits which are converted to an integer (could be a short, actually). Specific calculation example for the integer portion: for the 14-bit integer; all 8rightmost bits out of the bytes[0]size bytes are significant and must be shifted left by 6, and then added tofor the left 6 bits offractional part. If bytes[1]e.

For the float portion is 2, then the final 2 bits can have values 0, 1, 2, or 3 representing the fractions 0.0, 0.25, 0.5, and 0.75. The remaining leading bits are interpreted as the integer part.

The variable and method names are taken from C code here. I'll change those in response to commentsExample input:

  • bytes = { 0x00, 0x05 } // Binary 101
  • size = 2
  • e = 2

Example output: 1. Again25 // Integer portion is 1, my primary concern herefraction is whether I'm doing the bitwise math1/4.


Did I do it right (especially when bytesassuming arguments are converted to ints)already validated: e will never be more than 8, and size will never be more than 4)? Points of concern are order of operations properlyoperation, what happens bitwise when I promote a byte to an int and then shift it.

AWhile this function converts an FPE2 format number, I'm trying to make it a bit more general. A similar format, SP78, is used for Temperature, SP78temperature. The right mostrightmost 8 bits (divided by 256) are the fractional portion, the left 8 bits are a signed byte. (This method is not intended to handle the signed calculation but this is given as a reference.)

e will never be more than 8, and size will never be more than 4.

Edit #2: Final version of the code at the bottom of this class. Thanks all for the feedback.

I'm writing a method in Java that converts a byte array to a float. While my specific use case is converting an FPE2 format number, I'm trying to make it a bit more general.

In FPE2, the leftmost E (14) bits are converted to the integer portion of the number, and the rightmost 2 digits represent the floating point portion

Below is my attempt. Did I do it right (assuming I've checked arguments for validity: byte.length<=size<=4, e<=8)? Points of concern are order of operation, what happens bitwise when I promote a byte to an int and then shift it.

Example input:

  • bytes = { 0x00, 0x05 } // Binary 101
  • size = 2
  • e = 2

Example output: 1.25 // Integer portion is 1, fraction is 1/4.

Edit #1 to add clarification:

The array and size values are return values from another API, Apple's SMC interface. The array is a byte[32] value in a structure, where a second part of the structure states how many of the elements of the array are significant. In the use case, getting fan speed, bytes[0] and bytes[1] will be populated with data and size will have a value of 2.

The value of e represents how many bits are for floating points. For FPE2 the two bytes (size=2) have 14 bits which are converted to an integer (could be a short, actually). Specific calculation example for the integer portion: for the 14-bit integer; all 8 bits of bytes[0] are significant and must be shifted left by 6, and then added to the left 6 bits of bytes[1].

For the float portion, the final 2 bits can have values 0, 1, 2, or 3 representing the fractions 0.0, 0.25, 0.5, and 0.75.

The variable and method names are taken from C code here. I'll change those in response to comments. Again, my primary concern here is whether I'm doing the bitwise math (especially when bytes are converted to ints) and order of operations properly.

A similar format is used for Temperature, SP78. The right most 8 bits (divided by 256) are the fractional portion, the left 8 bits are a signed byte. (This method is not intended to handle the signed calculation but this is given as a reference.)

e will never be more than 8, and size will never be more than 4.

Edit #2: Final version of the code at the bottom of this class. Thanks all for the feedback.

Apple's System Management Controller uses FPE2 and SP78 as floating-point formats.

While writing a Java library that that interfaces with the SMC, I ported someone's C function to convert read a FPE2-formatted byte array as a float.

The bytes and size parameters come from Apple's SMC interface. The array is a byte[32] value in a structure, where a second part of the structure states how many of the elements of the array are significant. In the use case, getting fan speed, bytes[0] and bytes[1] will be populated with data and size will have a value of 2.

In FPE2, the value of e represents how many rightmost bits out of the size bytes are for the fractional part. If e is 2, then the final 2 bits can have values 0, 1, 2, or 3 representing the fractions 0.0, 0.25, 0.5, and 0.75. The remaining leading bits are interpreted as the integer part.

Example input:

  • bytes = { 0x00, 0x05 } // Binary 101
  • size = 2
  • e = 2

Example output: 1.25 // Integer portion is 1, fraction is 1/4.


Did I do it right (assuming arguments are already validated: e will never be more than 8, and size will never be more than 4)? Points of concern are order of operation, what happens bitwise when I promote a byte to an int and then shift it.

While this function converts an FPE2 format number, I'm trying to make it a bit more general. A similar format, SP78, is used for temperature. The rightmost 8 bits (divided by 256) are the fractional portion, the left 8 bits are a signed byte. (This method is not intended to handle the signed calculation but this is given as a reference.)

added 204 characters in body
Source Link
Loading
Added clarification
Source Link
Loading
added 250 characters in body
Source Link
Loading
added 747 characters in body
Source Link
Loading
Source Link
Loading