Ненулевой аргумент функции становится нулем внутри функции - PullRequest
4 голосов
/ 31 мая 2019

Я работаю над проектом C # / Unity с использованием 64-битной Ubuntu 18.04. У меня есть два нестатических класса, ClassA и ClassB, и внутри метода экземпляра classA.Foo() есть два вызова метода public static int ClassB.Floor(float x). В одном из двух мест, где Foo вызывает Floor, если я следую трассировке стека значений, переданных от classA.Foo до ClassB.Floor, ненулевые входные данные от Foo становятся 0 внутри Floor до того, как произойдет какое-либо вычисление.

Я искал stackoverflow, stackexchange и google в целом для людей, у которых были проблемы с переменными, изменяющими ненулевое значение на 0 при передаче в функции, либо на C #, либо на другом языке. Я нашел некоторые результаты, касающиеся передачи ссылочных и типовых значений, но ClassB.Floor получает float и возвращает int. Я подтвердил, что значения правильного типа (не двойные числа с плавающей запятой) вводятся в ClassB.Floor.

ClassB.Floor определяется как

public class ClassB : MonoBehaviour {
    [...]

    public static int Floor(float x) {
        int xi = (int)x;
        return x < xi ? xi - 1 : xi;
    }
}

Пример с комментариями к значению отладчика:

public class ClassA {
    # Set somewhere else during initialization, but definitely
    # exists by the time `Foo` is called.
    private GameObject gameObject;

    [...]

    public byte Foo(Vector3 pos) {  # pos: "(-17f, 0f, 15f)"
        [...]

        int x = ClassB.Floor(pos.x);  # x: -17
        Vector3 objPosition = gameObject.transform.position;  # objPosition: "(-16f, 0f, 0f)"
        float xx = objPosition.x;  # xx: -16f
        int px = ClassB.Floor(xx);  # px: 0

        [...]
    }
}

Таким образом, значение px установлено неправильно ClassB.Floor, даже если оно правильно работает при расчете x. Более того, если я захожу в отладчик и следую за ходом программы с int px = ClassB.Floor(xx); в classA.Foo до ClassB.Floor, я сразу же вижу это:

public static int Floor(float x) {  # x: 0

И выходное значение 0 правильно вычисляется из этого ввода 0. Если я использую функциональность Evaluate Expression отладчика Rider в любой момент во время выполнения программы после определения xx, ClassB.Floor(xx) возвращает правильное значение -16 даже если сама программа этого не делает.

В ходе выполнения программы через эту часть кода не генерируются ошибки или предупреждения. Кто-нибудь знает, что может быть причиной этого? Я действительно сбит с толку. Заранее спасибо!

[Update] Вот более минимальный пример, демонстрирующий такое же поведение. ClassB.Floor не имеет значения:

public class ClassA {
    public byte Foo(Vector3 pos) {  # pos: "(-17f, 0f, 15f)"
        float xx = -16f;  # xx: -16f
        int px = Mathf.FloorToInt(xx);  # px: 0
        return 0;
    }
}

То же самое дело: если я войду в Mathf.FloorToInt, определенный как

public static int FloorToInt(float f)
{
  return (int) Math.Floor((double) f);
}

Я считаю, что f=0 с самого начала функции, хотя xx=-16f.

1 Ответ

1 голос
/ 31 мая 2019

Это прекрасно работает для меня:

public class ClassB : MonoBehaviour
{
    void Start(){
        ClassA instance = new ClassA(gameObject);
        instance.Foo(new Vector3(10.5f,15.2f,20.8f));
    }
    public static int Floor(float x) // 10.5f and 12.19f
    {
        int xi = (int)x;
        return x < xi ? xi - 1 : xi;
    }
}


public class ClassA
{
    private GameObject gameObject;
    public ClassA(GameObject go){
        gameObject = go;
    }
    public byte Foo(Vector3 pos) // new Vector3(10.5f,15.2f,20.8f)
    {
        int x = ClassB.Floor(pos.x);  // 10
        //Debug.Log(x);
        Vector3 objPosition = gameObject.transform.position; // new Vector3(12.19f, 1f, -10f);
        float xx = objPosition.x; // 12.19f
        int px = ClassB.Floor(xx); //12
        //Debug.Log(px);
        return new byte();
    }
}
Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...